# MOS Technology 6502

Der MOS Technology 6502 ist ein 8-Bit-Mikroprozessor vom Unternehmen MOS Technology, der 1975 zunächst im Keramikgehäuse als MOS MCS 6502 auf den Markt kam. Wegen seines einfachen Aufbaus und vor allem seines im Vergleich zu den damals etablierten Intel- und Motorola-Prozessoren sehr niedrigen Preises bei vergleichbarer Leistungsfähigkeit wurde er in vielen Heimcomputern (zum Beispiel dem Commodore PET 2001 und dessen Nachfolger VC 20, dem Atari 800, Apple I, Apple II und BBC Micro), zahlreichen Schachcomputern (zum Beispiel dem Mephisto Polgar mit 5 oder 10 MHz), im weltweit ersten Skatcomputer Skat Champion, vielen Peripheriegeräten und zahlreichen Einplatinencomputern für Steuerungs- und Entwicklungszwecke eingesetzt. Der Prozessor wurde unter der Leitung von Chuck Peddle entwickelt.
Auch andere Mitglieder dieser Prozessorfamilie waren sehr erfolgreich, so der 6510, der Prozessor des Commodore 64, und der 6507 in den Atari-Spielkonsolen. Der Hauptkonkurrent von MOS Technology war damals Zilog, dessen Z80 zum Beispiel in vielen CP/M-Rechnern sowie in den Heimcomputern von Sinclair und Amstrad/Schneider zu finden war.

## Allgemeines

Das Design des 6502 wurde an das des 8-Bit-Prozessors Motorola 6800 angelehnt (nicht zu verwechseln mit dem jüngeren Motorola 68000) und orientierte sich an einem Einsatz des 6502 als Teil eines Mikrocontrollers. Die Befehlssätze von 6502 und MC6800 sind sich ähnlich, aber anstatt des einen 16-Bit-Index-Registers beim MC6800 werden beim 6502 zwei 8-Bit-Index-Register verwendet, deren Wert im Rahmen einer Befehlsausführung auf eine im Programmcode (absolute indizierte Adressierung) oder im Speicher (indirekte indizierte Adressierung) vorgegebene 16-Bit-Adresse addiert werden kann. Deswegen besteht hier für 6502-Programme die Notwendigkeit, Arrays, die größer als 256 Bytes sind, abschnittsweise anzusprechen.
Im Gegensatz dazu weisen im gleichen Zusammenhang andere 8-Bit-CPUs wie etwa der MC6800 oder der Z80 16-Bit-Index-Register auf, deren Wert zu einer im Programmcode vorgegebenen 8-Bit-Adresse addiert werden kann; die Möglichkeit, den Wert eines Indexregisters auf eine im Speicher vorhandene Adresse zu addieren, besteht bei diesen CPUs nicht.
Beispielsweise kann für einen Kopiervorgang ein Indexregister als Adresszähler verwendet werden, das innerhalb einer Schleife im Programmcode mit einem dedizierten Befehl um eins erhöht bzw. erniedrigt und anschließend noch vom selben Befehl auf den Wert null getestet wird. Der unmittelbar folgende Befehl beendet die Ausführung der Schleife, wenn zuvor der Wert null festgestellt wurde. Einen Befehl, der einen solchen Anwendungsfall noch effizienter ausführt, wie z. B. der LDIR-Befehl des Z80, besitzt der 6502 nicht.
Der einfacher gehaltene Befehlssatz führt allerdings dazu, dass 6502-Programme im Normalfall deutlich mehr Speicher benötigen als das Gleiche leistende MC6800- oder Z80-Programme; zudem sind standardkonforme Compiler für höhere Programmiersprachen wie etwa Pascal oder C für den 6502 deutlich schwieriger zu implementieren und erzeugen langsameren Code als entsprechende Compiler für andere 8-Bit-Prozessoren. Die Ursache hierfür ist vor allem die auf 256 Bytes beschränkte Größe des Stapelspeichers (siehe unten) des 6502, so dass der für die meisten modernen Hochsprachen nötige größere Stapelspeicher per Software nachgebildet werden muss. Um die Chipfläche klein zu halten, hat der 6502 des Weiteren nur einen Akkumulator im Gegensatz zu den zwei Akkumulatoren A und B im MC6800.
Als Cross-Compiler für die Programmiersprache C kann für den 6502 cc65 eingesetzt werden. Alternativ dazu kann mit dem 6502 eine einfache virtuelle CPU emuliert werden, womit dann sein Befehlssatz als Mikrocode behandelt wird.
Der 64 KB große Adressraum des 6502 teilt sich in mehrere Bereiche auf, die sich an den Page-Grenzen orientieren, an denen das High-Byte der 16-Bit-Adresse seinen Wert wechselt, d. h. jede Page stellt einen zusammenhängenden Block von 256 Bytes dar:
* Die Zeropage (die ersten 256 Bytes des Adressraums): sie dient praktisch als Registerbank, auf ihre Inhalte kann besonders schnell zugegriffen und jeweils zwei aufeinanderfolgende Bytes können als 16-Bit-Wert für diverse indirekte Adressierungsarten verwendet werden.
* Die folgenden 256 Bytes dienen als Stapelspeicher (Stack-Page), der von oben herab wächst. Wenn die in Anspruch genommene Stapeltiefe unter Kontrolle gehalten wird, werden oft die unteren Bereiche dieser Page für andere Zwecke benutzt (wie normales RAM).
* Der ganze restliche Bereich, bis auf die letzten 6 Bytes, kann beliebig für RAM, ROM oder Memory Mapped I/O verwendet werden. Der 6502 beherrscht, anders als etwa der Z80, kein Isolated I/O.
* In den letzten 6 Bytes des Adressraums (d. h. in den Adressen FFFA$_{16}$–FFFF$_{16}$) befinden sich drei 16-Bit-Zeiger (auch Vektoren genannt) für den „normalen“ Interrupt (IRQ) und BRK-Befehl (in FFFE$_{16}$–FFFF$_{16}$), das Reset-Signal (in FFFC$_{16}$–FFFD$_{16}$) und den Non-Maskable Interrupt (NMI) (in FFFA$_{16}$–FFFB$_{16}$), wobei stets die hier angegebene niedrigere Adresse die Bits 7 bis 0 und die höhere Adresse die Bits 15 bis 8 des jeweiligen 16-Bit-Zeigerwerts enthalten. Leitet die CPU die jeweilige Behandlung der Unterbrechungsanforderung mit einem BRK-Befehl ein, wird dabei der entsprechende Zeigerwert in den Programmzähler geladen (auch ein Reset führt zum Ausführen des BRK-Befehls, allerdings sind dabei die Schreibzugriffe der CPU deaktiviert). Damit diese Speicherstellen beim Reset definierte Werte enthalten, ist üblicherweise das Betriebssystem- oder Firmware-ROM am oberen Adressbereichsende angeordnet, während das RAM bei Adresse null beginnt. Bei einem Hardware-Reset wird also nicht wie bei vielen anderen Prozessoren einfach das ab Adresse null im Speicher vorgefundene Programm abgearbeitet, sondern der Vektor in den beiden Adressen FFFC$_{16}$–FFFD$_{16}$ wird in den Programmzähler kopiert und dann ab dieser Stelle das dort gespeicherte Programm abgearbeitet.
* Im Normalfall liest bzw. schreibt die CPU einmal pro Taktzyklus ein Byte aus einer bzw. in eine Speicherzelle im Adressraum. Falls nötig, kann jedoch der Lesezugriff der CPU verzögert werden, indem der RDY-Pin der CPU takt-synchron vom adressierten Speicher- oder Peripheriebaustein auf einen niedrigen Pegel gesetzt wird. Dadurch wird der interne Zustand der CPU eingefroren, d. h. die aktuelle Mikroinstruktion wird nicht zu Ende ausgeführt und der Adressbus unverändert angesteuert. Zudem befinden sich die Datenbustreiber der CPU (wie bei jedem Lesezugriff) im hochohmigen Zustand. Kann der Speicher- oder Peripheriebaustein schlussendlich das Byte am Datenbus bereitstellen, setzt er das RDY-Signal wieder takt-synchron auf einen hohen Pegel. Daraufhin liest die CPU das Datenbyte ein und stellt die aktuelle Mikroinstruktion fertig. Bei einem Schreibzugriff wird das RDY-Signal von der CPU allerdings ignoriert.
* Das RDY-Signal kann auch dazu benutzt werden, die CPU für einen DMA-Zugriff anzuhalten. Da die CPU erst bei einem Lesezugriff in den Wartezustand übergeht, können davor noch bis zu drei Taktzyklen vergehen (die drei aufeinander folgenden Schreibzugriffe des BRK-Befehls stellen hierbei den ungünstigsten Fall dar). Da während des DMA der Adressbus und die Lese-/Schreibleitung allein vom DMA-Controller angesteuert werden müssen und der 6502 diese – im Gegensatz zum Datenbus – ununterbrochen ansteuert, muss eine zusätzliche Schaltung eingesetzt werden, um die Ansteuerung zwischen DMA-Controller und 6502 umschalten zu können. Hierzu können Multiplexer-Chips wie z. B. der 74LS157 eingesetzt werden oder der Adressbus des 6502 wird über Puffer-Chips wie z. B. den 74LS244 geführt, deren Ausgänge hochohmig geschaltet werden können. Alternativ dazu kann beispielsweise der 6510 zum Einsatz kommen, dessen Adressbustreiber über seinen AEC-Pin hochohmig geschaltet werden können.
Für die Durchführung eines DMA zusammen mit dem Speicherzugriff des 6502 kommen neben der Verwendung des RDY-Signals noch weitere Methoden zum Einsatz:
Insofern es die Zugriffszeit des angesprochenen Speichers zulässt, kann ein DMA während der ersten Hälfte des Taktzyklus des 6502 stattfinden, da der 6502 nur während der zweiten Hälfte seines Taktzyklus eine Datenübertragung mit dem Speicher durchführt. Dieses Verfahren wird z. B. vom Video-Chip VIC II im C64 angewendet.
Weiterhin ist es möglich, das Signal am Takteingang Φ0 des 6502 auf einem niedrigen Pegel zu halten, so dass der interne Zustand des 6502 einfriert. Dies kann beim 6502 allerdings nur zeitlich begrenzt aufrechterhalten werden, da sich sein dynamischer Speicher, d. h. seine Kapazitäten, mit der Zeit entlädt. Diese Methode wird z. B. vom ANTIC-Chip im Atari 400 und Atari 800 eingesetzt, der den 6502 so bis zu ca. 54 μs anhält.
Technisch war MOS Technology mit dem 6502 durchaus innovativ:
* Er enthielt – im Gegensatz zu anderen Mikroprozessoren zu seiner Zeit – bereits einen integrierten Taktgenerator, der nur ein externes Taktsignal benötigte und selbst zwei nicht überlappende Taktsignale (Φ1 und Φ2) für seine internen Schaltkreise generierte.
* Er war der erste Mikroprozessor mit rudimentärer (zweistufiger) Pipeline-Architektur, d. h. bis während des Ladens des ersten Operanden des nachfolgenden Opcodes (also des auf den Opcode folgenden Bytes) konnte eine Mikroinstruktion des zuvor geladenen Opcodes noch intern ausgeführt werden. Eine echte Pipeline mit Überlappung der Lese- und Schreibzugriffe mehrerer Befehle gab es aber noch nicht.
* Sein Befehlssatz kann – zumindest im Vergleich zum Konkurrenzprodukt Intel 8080 – als „fast orthogonal“ angesehen werden.
* Anstelle von Mikrocode enthielt er ein PLA, dessen 130 Ausgänge in Abhängigkeit vom Maschinensprachebefehl, d. h. vom geladenen Opcode, und von dem internen Taktzähler die Ablaufsteuerung als erste Stufe übernahmen. Die zweite Stufe der Ablaufsteuerung stellte die Random Control Logic dar, die schließlich die Signale zur Steuerung des Datenpfads erzeugte.

## Technische Daten

| $^1$$_5$ | $^1$$_4$ | $^1$$_3$ | $^1$$_2$ | $^1$$_1$ | $^1$$_0$ | $^0$$_9$ | $^0$$_8$ | $^0$$_7$ | $^0$$_6$ | $^0$$_5$ | $^0$$_4$ | $^0$$_3$ | $^0$$_2$ | $^0$$_1$ | $^0$$_0$ | (Bitposition) |
| Hauptregister |||||||||||||||||
| | | | | | | | | A | A | A | A | A | A | A | A | Accumulator |
| Indexregister |||||||||||||||||
| | | | | | | | | X | X | X | X | X | X | X | X | X Index |
| | | | | | | | | Y | Y | Y | Y | Y | Y | Y | Y | Y Index |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | S | S | S | S | S | S | S | S | Stack Pointer |
| Programmzähler |||||||||||||||||
| PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | PC | Program Counter |
| Statusregister |||||||||||||||||
| | | | | | | | | N | V | - | B | D | I | Z | C | Processor Flags |
* Technologie: NMOS, HMOS, CMOS
* Anzahl der Transistoren (NMOS-Version): ca. 3510
* Taktfrequenz: traditionell 20 kHz bis 4 MHz; CMOS-Version 0 bis 14 MHz
* Taktzyklen je Befehl: 2 bis 7
* Adressraum: 64 KByte, dabei kein separater I/O-Adressraum (wie zum Beispiel beim Intel 8080), d. h. der gesamte I/O wird per Memory Mapped I/O realisiert.
* Adressbusbreite: 16 Bit
* Datenbusbreite: 8 Bit
* Interrupts: ein NMI, der durch eine fallende Flanke an seinem Pin ausgelöst wird; ein IRQ, der durch einen niedrigen Pegel an seinem Pin ausgelöst wird. Ein Software-Interrupt über den BRK-Befehl. Der Reset des 6502 ist schaltungstechnisch ebenfalls als Interrupt realisiert. Die Interrupt-Vektoren stehen an festen Adressen am Ende des Adressraums (FFFA$_{16}$ bis FFFF$_{16}$).
* Befehle: traditionell 56, CMOS-Version: 70
* Adressierungsarten: traditionell 13, CMOS-Version: 16
* Byte-Reihenfolge: Little Endian
* Register:
** Akkumulator, 8 Bit
** 2 Index-Register (X und Y), 8 Bit; der Wert je eines der Register wird als Offset zu einer 16-Bit-Adresse addiert (Ausnahme: Addition zu einer 8-Bit-Zeropage-Adresse), die je nach Adressierungsart im Maschinenbefehl selbst oder in der Zeropage steht.
** Stapelzeiger, 8 Bit; der Stapelzeiger wird als Low-Byte zusammen mit einem konstanten High-Byte (01$_{16}$) verwendet, um eine 16-Bit-Adresse zu erzeugen, wenn ein Befehl auf den Stapel zugreift. Somit umfasst der Stapel 256 Bytes im Adressbereich von 0100$_{16}$ bis 01FF$_{16}$ (die Page eins).
** Prozessorstatus-Register, 8 Bit (davon 1 Bit reserviert); Flag-Bit 7 bis Flag-Bit 0: Negative (N), Overflow (V), reserviert, Break (B), Decimal (D), Interrupt Disable (I), Zero (Z), Carry (C).
** Programmzähler, 16 Bit
Die Zeropage (Adressbereich 00xy$_{16}$) kann durch spezielle, schnellere Adressierungsarten angesprochen werden. Durch ihre Verwendung bei indizierter Adressierung kann sie auch als Registerbank oder Register-File angesehen werden.
Der Zustand des Break-Flags kann nur auf dem Stapel nach einem BRK-Befehl ausgelesen werden. Es hat keine eigenen Setz- und Testbefehle und wird auch von den Befehlen PLP, RTI und PHP nicht berücksichtigt, wobei PHP das Break-Flag auf dem Stapel als Teil des Prozessorstatus immer mit dem Wert eins angibt. Die CPU setzt bei einem erkannten NMI oder IRQ (sofern der IRQ über das Interrupt-Flag zugelassen ist) das Break-Flag auf null. Hierdurch wird als nächster Befehl ein BRK-Befehl ausgeführt (wenn nicht gerade schon ein BRK-Befehl ausgeführt wird) und somit nicht der gemäß dem Programmzähler nächste Befehl. Ein BRK-Befehl, der aufgrund eines IRQ oder Opcodes ausgeführt wird, verwendet denselben Interruptvektor. Anhand des Break-Flags lassen sich in diesem Fall dennoch die beiden Ursachen im Interrupt-Handler unterscheiden. Am Ende des BRK-Befehls hat das Break-Flag stets den Wert eins.

### Befehlssatz

Beispiele von Maschinenbefehlen bzw. deren Opcode und Mnemonics in Verbindung mit verschiedenen Adressierungsarten.
| Opcode | Mnemonic | Funktion |
| $A9 | LDA #$FF | Lädt ("LoaD") das Register "Akkumulator" mit FF$_{16}$ (255 dezimal). |
| $AD | LDA $C000 | Lädt den Akkumulator mit dem Speicherinhalt an der absoluten Adresse C000$_{16}$ (49152 dezimal). |
| $A1 | LDA ($24),Y | Lädt den Akkumulator mit dem Inhalt an jener Speicheradresse, welche sich ergibt, indem zu der 16-Bit-Zahl in den Adressen 24$_{16}$ und 25$_{16}$ der Inhalt des Y-Registers addiert wird. Siehe Zeropage, indirekte Adressierung. |
| $8D | STA $C000 | Speichert ("STore") den Inhalt des Akkumulators (ein Byte) an der Speicheradresse C000$_{16}$. |
| $6D | ADC $C001 | Addiert ("ADd with Carry-Flag") den Inhalt an der Speicheradresse C001$_{16}$ (ein Byte) zum Inhalt des Akkumulators (plus eins, falls das Carry-Flag gesetzt ist). |
| $C9 | CMP #$7F | Vergleicht ("CoMPare") den Inhalt des Akkumulators mit dem Zahlenwert 7F$_{16}$ (127 dezimal) und setzt die Flags entsprechend. |
| $E4 | CPX $C0 | Vergleicht den Inhalt des Registers X ("ComPare X") mit dem Inhalt der Speicherzelle an der absoluten Adresse C0$_{16}$. |
| $C0 | CPY #$C0 | Vergleicht den Inhalt des Registers Y ("ComPare Y") mit dem Zahlenwert C0$_{16}$. |
| $F0 | BEQ $FC00 | ("Branch if result is EQual") Verzweigt, wenn beispielsweise der letzte vorausgegangene Vergleich eine Gleichheit ergab (wird anhand des Z-Flags ermittelt). In diesem Fall würde das Maschinenprogramm an der Adresse FC00$_{16}$ (auch als Sprungadresse bezeichnet) weiter ausgeführt. Andernfalls wird der auf BEQ unmittelbar folgende Befehl als nächstes ausgeführt. Die Branch-Befehle erlauben nur die relative Adressierung mit einem vorzeichenbehafteten Offset im Bereich von -128 bis 127, also mit einem einzelnen Byte als Argument. Die CPU ermittelt die Sprungadresse, indem sie das Offset zur Adresse des auf den Branch-Befehl unmittelbar folgenden Befehls addiert. |
| $D0 | BNE $FC00 | ("Branch if result is Not Equal") Verzweigt, wenn beispielsweise der letzte vorausgegangene Vergleich eine Ungleichheit ergab. |
| $E8 | INX | ("INcrement X") Erhöht den Inhalt des Registers X um eins. |
| $88 | DEY | ("DEcrement Y") Verringert den Inhalt des Registers Y um eins. |
| $20 | JSR $FC00 | ("Jump to SubRoutine") Springt zur Subroutine (Unterprogramm) an der Adresse FC00$_{16}$. Die Rücksprungadresse, welche aus zwei Byte besteht und auf dem Stapel abgelegt wird, ist die Adresse des letzten Bytes des drei Byte langen JSR-Befehls. |
| $60 | RTS | ("ReTurn from Subroutine") Kehrt aus der Subroutine zurück und führt das Maschinenprogramm an der Rücksprungadresse aus, welche zuvor vom Stapel genommen und um eins erhöht wurde. |
| $00 | BRK | ("BReaK") Speichert am Anfang einer Interrupt-Behandlung bzw. als BRK-Befehl im Programmcode erst den Programmzähler bzw. den Programmzähler erhöht um zwei auf dem Stapel, dann das Statusbyte. Lädt den passenden Interrupt-Vektor in den Programmzähler. Hierbei hat das Laden des NMI-Vektors Priorität vor dem Laden des IRQ/BRK-Vektors. Setzt das I- und B-Flag und hebt die Registrierung eines NMI auf. |
| $EA | NOP | ("No OPeration") Befehl ohne Funktion, erhöht den Programmzähler um eins. |
In Assembler-Programmtexten des 6502 haben das Dollar- und Nummern-Zeichen sowie die Klammern folgende Bedeutung:
    $ – Der auf das $-Zeichen folgende Wert ist eine Hexadezimalzahl. Ohne $ stellt eine nur aus Ziffern bestehende Zeichenfolge die entsprechende Dezimalzahl dar. Ansonsten ist der Wert einer symbolischen Konstanten gemeint.
    # – Der auf das #-Zeichen folgende Wert ist eine direkt zu verwendende Zahl (immediate) und nicht eine Speicheradresse, deren Inhalt zu verwenden ist, d. h. das #-Zeichen kennzeichnet die sogenannte unmittelbare Adressierung.
    ( ) – Die in den Klammern genannte Speicheradresse ist nicht direkt zu verwenden, sondern sie enthält selbst wiederum die zu verwendende Speicheradresse (indirekte Adressierung, Zeiger).

### Opcode-Matrix

Alle Opcodes des dokumentierten 6502-Befehlssatzes :
| Adressierungsarten: A – Accumulator, # – unmittelbar, zpg – Zeropage, abs – absolut, ind – indirekt, X – indiziert indirekt mit X-Register, Y – indirekt indiziert mit Y-Register, rel – relativ |||||||||||||
| Höherwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble | Niederwertiges Nibble |
| Höherwertiges Nibble | 0 | 1 | 2 | 4 | 5 | 6 | 8 | 9 | A | C | D | E |
| 0 | BRK | ORA (ind,X) | | | ORA zpg | ASL zpg | PHP | ORA # | ASL A | | ORA abs | ASL abs |
| 1 | BPL rel | ORA (ind),Y | | | ORA zpg,X | ASL zpg,X | CLC | ORA abs,Y | | | ORA abs,X | ASL abs,X |
| 2 | JSR abs | AND (ind,X) | | BIT zpg | AND zpg | ROL zpg | PLP | AND # | ROL A | BIT abs | AND abs | ROL abs |
| 3 | BMI rel | AND (ind),Y | | | AND zpg,X | ROL zpg,X | SEC | AND abs,Y | | | AND abs,X | ROL abs,X |
| 4 | RTI | EOR (ind,X) | | | EOR zpg | LSR zpg | PHA | EOR # | LSR A | JMP abs | EOR abs | LSR abs |
| 5 | BVC rel | EOR (ind),Y | | | EOR zpg,X | LSR zpg,X | CLI | EOR abs,Y | | | EOR abs,X | LSR abs,X |
| 6 | RTS | ADC (ind,X) | | | ADC zpg | ROR zpg | PLA | ADC # | ROR A | JMP (ind) | ADC abs | ROR abs |
| 7 | BVS rel | ADC (ind),Y | | | ADC zpg,X | ROR zpg,X | SEI | ADC abs,Y | | | ADC abs,X | ROR abs,X |
| 8 | | STA (ind,X) | | STY zpg | STA zpg | STX zpg | DEY | | TXA | STY abs | STA abs | STX abs |
| 9 | BCC rel | STA (ind),Y | | STY zpg,X | STA zpg,X | STX zpg,Y | TYA | STA abs,Y | TXS | | STA abs,X | |
| A | LDY # | LDA (ind,X) | LDX # | LDY zpg | LDA zpg | LDX zpg | TAY | LDA # | TAX | LDY abs | LDA abs | LDX abs |
| B | BCS rel | LDA (ind),Y | | LDY zpg,X | LDA zpg,X | LDX zpg,Y | CLV | LDA abs,Y | TSX | LDY abs,X | LDA abs,X | LDX abs,Y |
| C | CPY # | CMP (ind,X) | | CPY zpg | CMP zpg | DEC zpg | INY | CMP # | DEX | CPY abs | CMP abs | DEC abs |
| D | BNE rel | CMP (ind),Y | | | CMP zpg,X | DEC zpg,X | CLD | CMP abs,Y | | | CMP abs,X | DEC abs,X |
| E | CPX # | SBC (ind,X) | | CPX zpg | SBC zpg | INC zpg | INX | SBC # | NOP | CPX abs | SBC abs | INC abs |
| F | BEQ rel | SBC (ind),Y | | | SBC zpg,X | INC zpg,X | SED | SBC abs,Y | | | SBC abs,X | INC abs,X |
| Fehlende Opcodes (z. B. 02) und alle Opcodes mit den niederwertigen Nibbles 3, 7, B und F sind nicht Bestandteil des 6502-Befehlssatzes. |||||||||||||
Es gibt von verschiedenen Herstellern CMOS-Versionen des 6502, die einen erweiterten Befehlssatz bzw. weitere Adressierungsarten haben. Dadurch kann es zu Änderungen bei den nachfolgend beschriebenen undokumentierten Opcodes kommen.

### Undokumentierte Opcodes

Der 6502 ist bekannt für eine ganze Reihe von Befehlen, die nicht in der offiziellen Dokumentation stehen, aber dennoch existieren und funktionieren. Umgangssprachlich nannte man solche Befehle illegale Opcodes. Nur 151 der prinzipiell 256 möglichen Opcodes sind reguläre Befehle. Aber auch unter den verbleibenden 105 nicht dokumentierten Codes gibt es etliche, die Funktionen haben, darunter durchaus nützliche. Einige Assembler unterstützen solche Befehle, es gibt jedoch keine einheitliche Vorschrift für ihre Benennung mit Mnemonics.
Mit vielen undokumentierten Opcodes lässt sich die Datenverarbeitung beschleunigen, da sie in wenigen Taktzyklen Funktionen erledigen, die sonst nur mit mehreren aufeinanderfolgenden Befehlen möglich sind, was insgesamt erheblich mehr Taktzyklen verbraucht. Dies birgt allerdings das Risiko, dass solche Befehle nicht auf allen produzierten CPUs gleichermaßen funktionieren oder ein mögliches Nachfolgemodell diese Befehle gar nicht beherrscht oder andere Funktionen ausführt, wodurch das Programm nicht mehr lauffähig wäre.
Wie bei den meisten regulären Befehlen gibt es auch für viele der undokumentierten Funktionen unterschiedliche Adressierungsarten und demzufolge auch unterschiedliche Opcodes. In der nachstehenden Tabelle werden – sofern nichts anderes angegeben ist – beispielhaft Opcodes für die Adressierungsart „absolut“ aufgeführt, die beiden auf den Opcode folgenden Bytes werden also als eine absolute Adresse interpretiert. Die Mnemonics sind inoffiziell.
| Opcode | Mnemonic | Funktion |
| $02 | HLT | ("HaLT") Ein-Byte-Befehl, hält den Prozessor an. Führt faktisch zum Absturz, der nur durch einen Reset zu beheben ist. |
| $0B | ANC #n | ("AND #n, N-Flag → C-Flag") Adressierungsart „immediate“. Führt eine UND-Verknüpfung des Akkumulators mit n durch, speichert das Ergebnis im Akkumulator und übernimmt danach den Wert des Negative-Flags (der mit dem Wert des siebten Bits des Akkumulators übereinstimmt) als neuen Wert für das Carry-Flag. |
| $0C | SKW | ("SKip next Word") Befehl ohne Funktion, erhöht den Programmzähler um drei und wird zum Überspringen der unmittelbar auf den Opcode folgenden zwei Bytes benutzt. |
| $0F | ASO $C000 | ("ASL, ORA") Führt den Befehl ASL mit dem Speicherinhalt an der Adresse C000$_{16}$ aus, anschließend wird eine ODER-Verknüpfung des Akkumulators mit dem neuen Speicherinhalt durchgeführt und das Ergebnis im Akkumulator gespeichert. |
| $2F | RLA $C001 | ("ROL, AND") Führt den Befehl ROL mit dem Speicherinhalt an der Adresse C001$_{16}$ aus, anschließend wird eine UND-Verknüpfung des Akkumulators mit dem neuen Speicherinhalt durchgeführt und das Ergebnis im Akkumulator gespeichert. |
| $4F | LSE $C002 | ("LSR, EOR") Führt den Befehl LSR mit dem Speicherinhalt an der Adresse C002$_{16}$ aus, anschließend wird eine EXKLUSIV-ODER-Verknüpfung des Akkumulators mit dem neuen Speicherinhalt durchgeführt und das Ergebnis im Akkumulator gespeichert. |
| $6F | RRA $C003 | ("ROR, ADC") Führt den Befehl ROR mit dem Speicherinhalt an der Adresse C003$_{16}$ aus, anschließend wird der neue Speicherinhalt zum Akkumulator addiert (plus eins, falls das Carry-Flag gesetzt ist). |
| $8B | XAA #n | ("TXA, AND #n") Adressierungsart „immediate“. Transferiert den Inhalt des Registers X in den Akkumulator, führt danach eine UND-Verknüpfung des Akkumulators mit n aus und speichert das Ergebnis im Akkumulator. |
| $8F | SAX $C004 | ("Store (A & X)") Soll den Inhalt des Akkumulators und des Registers X gleichzeitig an die Speicheradresse C004$_{16}$ schreiben. Dadurch, dass beide Registerinhalte gleichzeitig am internen Datenbus anliegen, ergibt sich eine UND-Verknüpfung der beiden Registerinhalte, deren Ergebnis an der Adresse C004$_{16}$ gespeichert wird. |
| $AF | LAX $C005 | ("LDA, LDX") Lädt den Speicherinhalt an der Adresse C005$_{16}$ in den Akkumulator sowie in das Register X. Einige Adressierungsarten von LAX können instabil sein, der Befehl also zu unvorhersehbaren Seiteneffekten führen. |
| $CF | DCM $C006 | ("DEC, CMP") Verringert den Wert an der Speicheradresse C006$_{16}$ um eins und vergleicht anschließend den neuen Speicherinhalt mit dem Inhalt des Akkumulators. |
| $EF | INS $C007 | ("INC, SBC") Erhöht den Wert an der Speicheradresse C007$_{16}$ um eins und subtrahiert anschließend den neuen Speicherinhalt vom Inhalt des Akkumulators (zusätzlich um eins, falls das Carry-Flag den Wert null besitzt). |

## Beispielprogramm

Das nachfolgende Beispielprogramm ermittelt das Maximum einer Bytefolge. Die erste Spalte zeigt die Speicheradressen gefolgt vom Maschinencode als Hexadezimalzahlen. Die zweite Spalte zeigt den dazugehörigen Quellcode für einen 6502-Assembler.
| 0040 0040 00 0041 03 0042 D5 0043 1C 0044 39 0200 0200 A6 41 0202 A9 00 0204 D5 41 0206 B0 02 0208 B5 41 020A CA 020B D0 F7 020D 85 40 | ; Das Programm ab der Adresse findmax findet das Maximum einer Folge von Bytes, ; wobei jedes Byte einen Wert von 0 bis 255 annehmen kann. ; Die Länge der Zahlenfolge befindet sich an der Adresse len und muss einen Wert ; im Bereich von 1 bis 255 aufweisen. ; Die Folgenglieder sind unmittelbar nach dem Längenbyte gespeichert. ; Das ermittelte Maximum im Bereich von 0 bis 255 wird an der Adresse max gespeichert. ; Die im Programmcode gewählten Adressen und die Bytefolge sind beispielhaft gewählt. ORG $40 max DS 1 ; Speicherplatz für Maximum len DC 3 ; Länge der Zahlenfolge DC 213 ; 1. Folgenglied DC 28 ; 2. Folgenglied DC 57 ; 3. Folgenglied ORG $0200 ; Startadresse des Programmcodes findmax LDX len ; X-Register (X) mit Folgenlänge laden LDA #0 ; Akkumulator (A) mit null (kleinster Wert) initialisieren next CMP len,X ; A mit aktuellem Folgenglied vergleichen BCS notmax ; verzweige an die Stelle notmax, falls Folgenglied nicht größer als A ist LDA len,X ; A mit aktuellem Folgenglied laden, ist neues Maximum notmax DEX ; X um eins vermindern BNE next ; verzweige an die Stelle next, falls X größer als null ist STA max ; speichere gefundenes Maximum an der Adresse max |

## Taktvarianten des MOS 6502

Der Prozessor existiert in vier Varianten mit jeweils unterschiedlicher Taktfrequenz:
* ≈1 MHz: MOS 6502
** in den Commodore-PET- und -CBM-Modellen PET 2001 bis CBM 8296 sowie im VC 20 und den Floppy-Laufwerken VC1540 und VC1541
** im Apple I, Apple II, im Apple II+, und im nicht erweiterten Apple IIe
** im Ohio Scientific Superboard II
** in den Rechnern der Ohio-Scientific-Challenger-Serie
* 2 MHz: MOS 6502A
** im Apple III
** in den 8-Bit-Atari-Homecomputern 400 und 800 mit 1,79 MHz (1,77 MHz im PAL-Modus)
** in einigen Floppy-Laufwerken von Commodore, zum Beispiel VC1570, VC1571 und VC1581
** im Skat Champion, dem weltweit ersten Skatcomputer von Novag Industries Ltd.
* 3 MHz: MOS 6502B
* 4 MHz: MOS 6502C

## Varianten anderer Hersteller (Second Source und unlizenziert)

* Rockwell
** R6502P (1 MHz)
** R6502AP (2 MHz)
** R6502ACE (2 MHz, Keramikgehäuse, erweiterter Temperaturbereich für industrielle Verwendung)
* UMC
** UM6502 (1 MHz)
** UM6502A (2 MHz)
* Synertek
** SYP6502 (1 MHz)
** SYP6502A (2 MHz)
* KMT-Prawez
** SM630 (CM630) (bulgarischer Klon des 6502)

## Abgeleitete Designs

* Ricoh RP2A03
** Von Ricoh für Nintendo produziert
** Eingesetzt in der NES-Spielkonsole (NTSC-Version)
** Deaktivierte BCD-Arithmetik
** 1,79 MHz CPU-Taktfrequenz
* Ricoh RP2A07
** PAL-Version des RP2A03
** Geänderter Frequenzteiler und an PAL angepasster Farbträger
** Eingesetzt in europäischen und australischen Versionen der NES-Spielkonsole
** 1,66 MHz CPU-Taktfrequenz
* YAMAHA YM-2002
** Eingesetzt in der YAMAHA CENTRAL PROCESSING UNIT PU-1-10 bzw. PU-1-20 als Bestandteil des YIS (YAMAHA Integrated System)
* NCR 81489; UMC UA6588F
** Mikrocontroller mit 6502-Kern, I/O-Ports, LCD-Controller, Timer, serieller Schnittstelle und ROM
** Eingesetzt in der Handheld-Spielkonsole Gamate von Bit Corporation
** 2,2 MHz CPU-Taktfrequenz
* Renesas 38000
** Mikrocontroller-Familie von Renesas Technology mit Renesas-740-Kern. Siehe Renesas 740
* Renesas 740
** Mikrocontrollerfamilie von Renesas Technology (vormals Mitsubishi Electric)
** Basierend auf dem WDC W65C02S
** Bis zu 60 KB ROM/PROM/Flash integriert
** Bis zu 2 KB RAM integriert
** Bis zu 8 MHz interne Taktfrequenz
** Zusätzliche Befehle im Vergleich zum 6502, u. a.
*** Multiplikation
*** Division
*** Befehle zum Setzen einzelner Bits
*** Befehle zum direkten Setzen eines Bytes im Speicher
*** Unbedingter relativer Sprung
*** Berechnung des Einerkomplements
*** Befehle zum Stoppen der CPU
** Zusätzliche Adressierungsarten im Vergleich zum 6502
*** Special Page: Sprungziel liegt in der Page FF$_{16}$
*** Accumulator Bit: Auswahl eines Bits im Akkumulator
*** Zero Page Bit: Auswahl eines Bits in der Page null
*** Accumulator Bit Relative: bedingter Sprung basierend auf einem Bitwert im Akkumulator
*** Zero Page Bit Relative: bedingter Sprung basierend auf einem Bitwert in der Page null
* SUNPLUS CPU6502
** Mikrocontrollerfamilie von Sunplus Technology mit CPU6502-Kern
** Verwendet die 6502-Opcodes oder alternativ abweichende Sunplus-Opcodes
** Kein BRK-Befehl und kein Break-Flag im Vergleich zum 6502
** Bei einigen Mikrocontrollern eingeschränkter Befehlssatz und abweichende Anzahl an Taktzyklen pro Befehl im Vergleich zum 6502
** Eingesetzt z. B. im Taschenrechner HP 35s
* Hudson Soft HuC6280
** CMOS-Mikrocontroller
** Entwickelt von Hudson Soft und NEC auf Basis des R65C02-Befehlssatzes
** Zusätzliche Befehle zum Nullsetzen und Tauschen der Inhalte des A-, X- und Y-Registers
** Zusätzliche Befehle zum Kopieren des Inhalts von Speicherbereichen
** 8 Mapping-Register, um 64 K logische Adressen in einen 2-MB-Adressraum physikalischer Adressen einzubetten
** Enthält zudem 7-Bit-Timer, 8-Bit-Eingabeport, 8-Bit-Ausgabeport sowie einen programmierbaren Klanggenerator mit sechs Kanälen
** Bis zu 21,48 MHz Taktfrequenz
** Eingesetzt in NECs PC Engine aka TurboGrafx-16 mit bis zu 7,16 MHz Taktfrequenz
* Atari C014377
** Atari-eigene Bezeichnung für einen unmodifizierten MOS 6502
** Gelegentlich in der Atari-Literatur als „6502B“ bezeichnet
** Eingesetzt in den 8-Bit-Homecomputern Atari 400 und Atari 800 mit 1,77 MHz Taktfrequenz (PAL-Version) bzw. 1,79 MHz Taktfrequenz (NTSC-Version)
* Atari C014806 („SALLY“)
** Atari-eigene Bezeichnung für einen erweiterten MOS 6502, der zusätzlich die Logik-Chips der ältesten CPU-Karte des Atari 400 und Atari 800 zum Stoppen des Taktsignals und zum Trennen der CPU vom Adressbus und der Lese-/Schreibleitung enthält
** Gelegentlich in der Atari-Literatur als „6502C“ bezeichnet
** HALT-Signal-Eingang an Pin 35
** Bis zu 1,77 MHz Taktfrequenz (PAL-Version) bzw. 1,79 MHz Taktfrequenz (NTSC-Version)
** Eingesetzt in Ataris 8-Bit-Homecomputerserien XL und XE sowie in den Spielkonsolen Atari 5200 und Atari 7800
* WDC W65C02S; Rockwell R65C02, R65C102, R65C112; GTE/CMD G65SC02, G65SC102, G65SC112
** Entwickelt von Western Design Center (WDC)
** CMOS-Mikroprozessoren, kompatibel mit MCS6502
** Alle Mikroprozessoren weisen im Vergleich zum MCS6502 zusätzlich die Befehle BRA, PHX, PHY, PLX, PLY, STZ, TRB, TSB auf
** Bei den Mikroprozessoren der R65C00-Familie und dem WDC W65C02S kommen noch die Befehle BBR, BBS, RMB, SMB hinzu
** Allein der W65C02S besitzt darüber hinaus die beiden Befehle WAI und STP
** Zusätzliche Adressierungsmodi (indirekte Adressierung in der Page null; indirekte indizierte Adressierung beim JMP-Befehl)
** Keine illegalen Opcodes (jeder illegale Opcode gleicht in seiner Wirkung einem oder mehreren aufeinander folgenden NOP-Befehlen)
** Gültiges N-, V- und Z-Flag nach einer Addition oder Subtraktion in BCD-Arithmetik
** Einige Befehle benötigen unter bestimmten Voraussetzungen weniger oder mehr Taktzyklen als beim MCS6502
** Maximale Taktfrequenz von 14 MHz beim W65C02S (ursprünglich bei allen Versionen 1 bis 4 MHz Taktfrequenz)
** Das RDY-Signal, wenn es auf einem niedrigen Pegel gehalten wird, hält nun den Mikroprozessor im Vergleich zum MCS6502 auch bei Schreibzugriffen an
** Die WDC-Variante im Dual in-line package ist nicht pinkompatibel zum MCS6502, lässt sich aber ggf. mit geringen Änderungen auf der Platine dennoch als Ersatz für einen MCS6502 einsetzen
** R65C102, R65C112, G65SC102 und G65SC112 sind für Multiprozessorbetrieb ausgelegt und zeigen deswegen an ihrem ML-Pin das Abarbeiten eines Read-Modify-Write-Befehls an; damit kann sichergestellt werden, dass ein solcher Befehl unterbrechungsfrei ausgeführt wird
** R65C102 und G65SC102 können bei Multiprozessorbetrieb das Taktsignal für den R65C112 und den G65SC112 erzeugen
** In der Vergangenheit hergestellt von GTE, Rockwell, Synertek, NCR, Sanyo und anderen; aktuell gefertigt bei TSMC auf Basis eines 0,6-μm-CMOS-Prozesses (Stand 2023)
** W65C02S als Prozessorkern eingesetzt im Watara Supervision
** R65C02 eingesetzt im erweiterten Apple IIe
** G65SC02 eingesetzt im Apple IIc sowie als Prozessorkern im ersten Atari Lynx mit bis zu 4 MHz Taktfrequenz
** R65C102 als Coprozessor eingesetzt im BBC Micro
** G65SC102 eingesetzt im Commodore LCD
* CSG 65CE02
** CMOS-Mikroprozessor
** 1988 entwickelt von der Commodore Semiconductor Group (CSG) basierend auf dem Rockwell R65C02
** Zusätzliches Basepage-Register, um die Zeropage-Adressierungsarten durch Basepage-Adressierungsarten zu ersetzen
** Zusätzliches Z-Indexregister, welches anstatt des Y-Indexregisters bei der indirekten indizierten Adressierung verwendet werden kann
** Wahlweise frei wählbare Page für 8-Bit-Stapelzeiger oder 16-Bit-Stapelzeiger
** Zusätzliche 16-Bit-RMW-Befehle
** Relative Sprünge und Unterprogrammaufrufe auch mit 16-Bit-Offset
** Indirekte indizierte Adressierung, bei der die Summe aus Stapelzeiger und Offset im Programmcode die Zeropage-Adresse der Adressierungsart (Indirect),Y ersetzt
** 2 bis 10 MHz Taktfrequenz
** Eingesetzt im Commodore 65 als Prozessorkern im CSG-Mikrocontroller 4510 (mit bis zu 3,5 MHz Taktfrequenz) und in der Commodore A2232 Multiport Serial Card (mit bis zu 3,5 MHz Taktfrequenz)
* MOS 6501
** Gehäuse- und signalkompatibel (nicht softwarekompatibel) zum Motorola 6800 (ohne den – oben erwähnten – internen Taktgenerator des 6502). Musste nach einer Patentverletzungsklage Motorolas im März 1976 eingestellt werden.
* MOS 6503, 6505, 6506, 6513, 6515; Rockwell R6503, R6505, R6506, R6513, R6515; Synertek SY6503, SY6505, SY6506, SY6513, SY6515
** Mikroprozessoren mit 12-Bit-Adressbus (4 KB)
* MOS 6504, 6507; Rockwell R6504, R6507; Synertek SY6504, SY6507; UMC UM6507
** Mikroprozessoren mit 13-Bit-Adressbus (8 KB)
** 6504 eingesetzt z. B. im Commodore-Nadeldrucker MPS-802 und im Commodore-Schachcomputer Chessmate
** 6507 eingesetzt z. B. im Atari 2600 mit 1,19 MHz-Taktfrequenz und im Atari-Diskettenlaufwerk 1050
* MOS 6509
** Mikroprozessor mit 20-Bit-Adressbus (1 MB) und mit Unterstützung für Bankswitching
** Zwei zusätzliche 4-Bit-Register zur Auswahl der Memory Bank. Die Befehle LDA (Indirect),Y und STA (Indirect),Y verwenden während des Zugriffs auf den Speicherinhalt an der effektiven Adresse das Indirect-Register, ansonsten wird stets das Execute-Register verwendet
** Eingesetzt in den Commodore-PET-II-Modellen (CBM 500, 600 und 700)
* MOS 6510, 8500 (HMOS-Herstellungsprozess)
** Mikroprozessor mit der Möglichkeit, seine Adressbustreiber über seinen AEC-Pin hochohmig zu schalten, so dass ein DMA-Controller neben der CPU auf den Speicher zugreifen kann
** Zusätzlicher interner 8-Bit-I/O-Port, von dem je nach Variante gemäß Datenblatt sechs oder acht Anschlüsse herausgeführt werden
** Eingesetzt im C64 mit 985 kHz (PAL-Version) bzw. 1,023 MHz (NTSC-Version) Taktfrequenz und mit sechs herausgeführten Anschlüssen des internen I/O-Ports
** Eingesetzt im Diskettenlaufwerk VC1551 mit 2 MHz Taktfrequenz als 6510T
* MOS 7501, 8501 (HMOS-Herstellungsprozess)
** Mikroprozessor mit der Möglichkeit, seine Adressbustreiber über seinen AEC-Pin hochohmig zu schalten, so dass ein DMA-Controller neben der CPU auf den Speicher zugreifen kann
** Zusätzlicher interner 8-Bit-I/O-Port, von dem sieben Anschlüsse herausgeführt werden
** Zusätzlicher GATE-IN-Pin, um die Lese-/Schreibleitung hochohmig schalten zu können
** Maximale Taktfrequenz von 2 MHz
** Eingesetzt im Commodore 16 und Commodore Plus/4 mit einer Taktfrequenz von bis zu 1,788 MHz
* MOS 8502 (HMOS-II-Herstellungsprozess)
** Mikroprozessor mit der Möglichkeit, seine Adressbustreiber über seinen AEC-Pin hochohmig zu schalten, so dass ein DMA-Controller neben der CPU auf den Speicher zugreifen kann
** Zusätzlicher interner 8-Bit-I/O-Port, von dem sieben Anschlüsse herausgeführt werden
** Maximale Taktfrequenz von 2,04 MHz
** Eingesetzt im C128
* MOS 6500/1; Rockwell R6500/1; CSG 6570, 6571
** Mikrocontroller mit 2 KB ROM, 64 Bytes RAM, vier 8-Bit-I/O-Ports und einem 16-Bit-Zähler
** 6500/1 eingesetzt z. B. im Plotter Commodore 1520 und in der Tastatur des Amiga 1000
** 6570, 6571 eingesetzt z. B. in Amiga-Tastaturen
* Rockwell R6511Q, R6500/13
** Mikrocontroller mit I/O-Ports, Timern, serieller Schnittstelle und 192-Byte-RAM; R6500/13 optional mit 256-Byte-ROM
** Zusätzliche Befehle zum Setzen und Testen von Bits
* Rockwell R65F11, R65F12
** Varianten des R6511Q mit integriertem Forth-Interpreter (3 KB on-chip ROM, enthält die Routinen für RSC-FORTH)
* WDC W65C134S
** CMOS-Mikrocontroller
** Entwickelt von Western Design Center (WDC)
** Enthält u. a. einen W65C02S-Prozessorkern, 4 KB ROM mit Speichermonitor-Software, 192 Bytes RAM, vier 16-Bit-Timer, UART, sechs 8-Bit-I/O-Ports und einen 8-Bit-Output-Port
** Bis zu 8 MHz Taktfrequenz
* Sitronix ST2205U
** Mikrocontroller in digitalen Bilderrahmen
* NOVATEK NT6868A
** Mikrocontroller für Tastaturanwendungen
* WDC W65C802
** 8/16–Bit-CMOS-Mikroprozessor
** Entwickelt von Western Design Center (WDC)
** Variante des WDC W65C816S, welche pinkompatibel zum MCS6502 ist, daher wie beim MCS6502 64 K Adressen ansprechbar
** Zum direkten Austausch des MCS6502 in bereits bestehenden Schaltungen gedacht
** Bis zu 8 MHz Taktfrequenz
* WDC W65C816S
** 8/16–Bit-CMOS-Mikroprozessor
** Entwickelt von Western Design Center (WDC)
** Eingesetzt z. B. im Apple IIgs, Nintendo SNES (als Prozessorkern im Ricoh 5A22) und der Beschleunigungskarte SuperCPU für den C64 und C128
** 16-Bit-Register und 16-Bit-ALU
** 16-Bit-Adressbus (24 Adressbits werden innerhalb eines Taktzyklus im Zeitmultiplexing übertragen, so dass 16 MB adressiert werden können)
** Externer 8-Bit-Datenbus und interner 16-Bit-Datenbus (zur Übertragung eines 16-Bit-Werts über den externen Datenbus sind zwei Taktzyklen notwendig)
** Emulationsmodus für die Prozessoren der 6500-Familie
** Bis zu 20 MHz Taktfrequenz
** Braucht im Vergleich zum 6502 wegen des zusätzlichen Adressbytes für viele Befehle einen Takt länger
* Ricoh 5A22
** Mikrocontroller von Ricoh mit W65C816S-Prozessorkern
** Eingesetzt in der SNES-Spielkonsole

## Trivia

* Der fiktive Roboter Bender aus der Zeichentrickserie Futurama hat einen 6502-Prozessor als CPU (Staffel 2, Episode 4 – Die Party mit Slurm McKenzie).
* Im Spielfilm Terminator (1984) wird aus Sicht des Terminators ein 6502-Assembler-Programm für den Apple II angezeigt. Zudem ist eine Ausgabe des Prüfsummen-Programms Key Perfect (in der Version 4.0), das im Nibble Magazine veröffentlicht wurde, zu sehen.
* WDC lässt den W65C02S weiterhin produzieren und er kann käuflich erworben werden (Stand 2023).
* Für den MCS6502-Mikroprozessor wurde eine Simulation seiner Transistor-Ebene in Software bzw. in Hardware auf einer etwa 30,5 cm × 38 cm großen Platine (The MOnSter 6502) erstellt.