Section courante

A propos

Section administrative du site

Architecture et registres

Le 6502 est un microprocesseur 8 bits a architecture CISC simplifiée. Conçu par Chuck Peddle et Bill Mensch chez MOS Technology en 1975, il se distingue par une conception extrêmement efficace avec un nombre minimal de transistors (environ 3 510), ce qui a permis un coût de fabrication très bas.

L'architecture interne comprend :

Le 6502 ne dispose pas de registres de segment ni de mécanisme de protection mémoire. L'espace d'adressage est un espace plat de 64 Ko directement accessible.

Caractéristiques techniques du 6502 original :

Spécification Description
Fréquence d'horloge 1 MHz (6502), 2 MHz (6502A), 3 MHz (6502B)
Transistors Environ 3 510 (NMOS)
Boîtier DIP 40 broches
Technologie NMOS (puis CMOS pour le 65C02)
Alimentation +5V (une seule tension)
Ensemble d'instructions 56 instructions de base (151 opcodes valides)
Modes d'adressage 13
Largeur des données 8 bits
Largeur des adresses 16 bits
Espace adressable 64 Ko
Taille de la pile 256 octets (page 1)

Le 6502 se distingue des processeurs concurrents (8080, Z80, 6800) par son nombre de registres réduit, compense par l'accès rapide à la page zéro ($0000-$00FF) qui fonctionne comme un ensemble de 256 pseudo-registres de 8 bits (ou 128 pseudo-registres de 16 bits pour les pointeurs indirects).

Accumulateur (A)

L'accumulateur est le registre central du 6502. C'est le seul registre capable d'effectuer des opérations arithmétiques et logiques.

Taille : 8 bits (valeurs de $00 a $FF)

Opérations supportées :

Transfert de données :

Instruction Description
LDA Charger l'accumulateur depuis la mémoire
STA Entreposer l'accumulateur en mémoire
TAX Transférer A vers X
TAY Transférer A vers Y
TXA Transférer X vers A
TYA Transférer Y vers A

Arithmétique :

Instruction Description
ADC Addition avec retenue (A := A + opérande + C)
SBC Soustraction avec retenue (A := A - opérande - NOT(C))

Logique :

Instruction Description
AND ET logique (A := A AND opérande)
ORA OU logique (A := A OR opérande)
EOR OU exclusif (A := A XOR opérande)

Décalage et rotation (mode accumulateur) :

Instruction Description
ASL A Décalage a gauche (bit 7 → C, 0 → bit 0)
LSR A Décalage a droite (bit 0 → C, 0 → bit 7)
ROL A Rotation a gauche via C (bit 7 → C, C → bit 0)
ROR A Rotation a droite via C (bit 0 → C, C → bit 7)

Comparaison :

Instruction Description
CMP Comparer A avec un opérande (positionne N, Z, C)

Pile :

Instruction Description
PHA Empiler A (Push Accumulator)
PLA Dépiler A (Pull Accumulator)

Particularités :

Exemples :

  1. LDA #$42          ; A = $42 (chargement immediat)
  2. LDA $80           ; A = contenu de l'adresse $0080 (page zero)
  3. LDA $1234         ; A = contenu de l'adresse $1234 (absolu)
  4. STA $0400         ; stocker A a l'adresse $0400
  5. ADC #$10          ; A = A + $10 + C
  6. AND #$0F          ; masquer les 4 bits hauts (A = A AND $0F)
  7. ASL A             ; decaler A a gauche (multiplication par 2)
  8. CMP #$80          ; comparer A avec $80

Registres d'index (X et Y)

Le 6502 dispose de deux registres d'index de 8 bits, X et Y. Bien qu'ils partagent certaines fonctions, ils ne sont pas entièrement interchangeables car chacun supporte des modes d'adressage différents.

Taille : 8 bits chacun (valeurs de $00 a $FF)

Registre X :

Modes d'adressage supportes :

Instructions spécifiques :

Instruction Description
LDX Charger X depuis la mémoire
STX Entreposer X en mémoire
TAX Transférer A vers X
TXA Transférer X vers A
TSX Transférer SP vers X
TXS TransférerX vers SP
INX Incrémenter X (X := X + 1)
DEX Décrémenter X (X := X - 1)
CPX Comparer X avec un opérande

Utilisation typique :

Registre Y :

Modes d'adressage supportes :

Instructions spécifiques :

Instruction Description
LDY Charger Y depuis la mémoire
STY Entreposer Y en mémoire
TAY Transférer A vers Y
TYA Transférer Y vers A
INY Incrémenter Y (Y := Y + 1)
DEY Décrémenter Y (Y := Y - 1)
CPY Comparer Y avec un opérande

Utilisation typique :

Différences entre X et Y :

Fonctionnalité X Y
Page zéro indexe (LDA/STA/etc.) Oui (,X) Non *
Page zéro indexe (LDX/STX) Non ** Oui (,Y)
Absolu indexe Oui (,X) Oui (,Y)
Indirect pre-indexe (IND,X) Oui Non
Indirect post-indexe (IND),Y Non Oui
Transfert depuis/vers SP Oui (TSX/TXS) Non

Exemples :

  1. LDX #$00          ; X = 0
  2. LDY #$05          ; Y = 5
  3. LDA Table,X       ; A = contenu de Table + X
  4. STA Buffer,Y      ; stocker A a Buffer + Y
  5. INX               ; X = X + 1
  6. DEY               ; Y = Y - 1
  7. CPX #$10          ; comparer X avec $10
  8. BNE Loop          ; boucler si X != $10
  9. LDA ($80,X)       ; indirect pre-indexe par X
  10. LDA ($80),Y       ; indirect post-indexe par Y

Pointeur de pile (SP, Stack Pointer)

Le pointeur de pile du 6502 est un registre de 8 bits pointant vers le prochain emplacement libre dans la pile. Contrairement aux processeurs comme le Z80 ou le 68000 qui ont un pointeur de pile de 16 bits, le SP du 6502 est limite a 8 bits, ce qui restreint la pile a une zone fixe de 256 octets.

Taille : 8 bits (valeurs de $00 a $FF)

Emplacement de la pile :

Fonctionnement :

Initialisation :

Instructions utilisant la pile :

Empilage/dépilage explicite :

Instruction Description
PHA Empiler A
([$0100+SP] := A, SP := SP - 1)
PLA Dépiler A
(SP := SP + 1, A := [$0100+SP])
PHP Empiler P (état)
([$0100+SP] := P, SP := SP - 1)
PLP Dépiler P (état)
(SP := SP + 1, P := [$0100+SP])

Empilage/dépilage implicite :

Instruction Description
JSR Appel de sous-routine - empile PC-1 (2 octets, poids fort puis poids faible)
RTS Retour de sous-routine - depile PC-1 puis ajoute 1
BRK Interruption logicielle - empile PC+1 puis P
RTI Retour d'interruption - dépile P puis PC
IRQ Interruption matérielle - empile PC puis P
NMI Interruption non masquable - empile PC puis P

Transfert avec le registre X :

Instruction Description
TSX Transférer SP vers X (X := SP, positionne N et Z)
TXS Transférer X vers SP (SP := X, ne modifie PAS les drapeaux)

Utilisation de la pile par JSR/RTS :

L'instruction JSR empile l'adresse de retour MOINS 1 (c'est-a-dire l'adresse du dernier octet de l'instruction JSR, et non l'adresse de l'instruction suivante). L'instruction RTS dépile cette adresse et lui ajoute 1 pour obtenir l'adresse de la prochaine instruction a exécuter.

Exemple : si JSR se trouve a l'adresse $1000 (3 octets : $20 low high), l'adresse empilée est $1002, et RTS chargera PC = $1002 + 1 = $1003.

Séquence JSR a $1000 :

[$0100+SP] := $10 (poids fort de $1002)
SP := SP - 1
[$0100+SP] := $02 (poids faible de $1002)
SP := SP - 1
PC := adresse cible

Note sur la capacité de la pile :

Compteur programme (PC, Program Counter)

Le compteur programme est le seul registre 16 bits du 6502. Il contient l'adresse de la prochaine instruction a exécuter.

Taille : 16 bits (adresses de $0000 a $FFFF)

Caractéristiques :

Le 6502 entrepose les adresses en format little-endian (poids faible en premier). Le PC est charge depuis la mémoire dans cet ordre : l'octet a l'adresse la plus basse contient le poids faible, et l'octet a l'adresse suivante contient le poids fort.

Branchements relatifs :

Registre d'état du processeur (P, Processor Status)

Le registre d'état est un registre de 8 bits contenant les drapeaux de condition et de contrôle du processeur.

Taille : 8 bits

Organisation :

Bit Sigle Nom Description
7 N Négative 1 si le bit 7 du résultat est a 1 (le résultat est négatif en complément à deux)
6 V Overflow 1 si débordement en complément a deux (le signe du résultat est incorrect)
5 - (inutilisé) Toujours lu comme 1
4 B Break 1 si l'interruption est causée par BRK, 0 si c'est une interruption matérielle (IRQ/NMI). N'existe pas physiquement dans le registre; n'est visible que sur la pile après PHP ou BRK.
3 D Decimal Active le mode BCD pour ADC et SBC (0 = binaire, 1 = BCD)
2 I Interrupt Masque les interruptions IRQ quand a 1 (les NMI ne sont PAS masquées)
1 Z Zero 1 si le résultat est zéro ($00)
0 C Carry Retenue pour l'arithmétique et les décalages/rotations

Schéma visuel :

Détail de chaque drapeau :

C (Carry, bit 0) :

Z (Zero, bit 1) :

I (Interrupt Disable, bit 2) :

D (Decimal, bit 3) :

B (Break, bit 4) :

V (Overflow, bit 6) :

N (Negative, bit 7) :

Bit 5 (inutilisé) :

Instructions agissant sur P :

Instruction Description
PHP Empiler P sur la pile (avec B=1 et bit 5=1)
PLP Dépiler P depuis la pile (restaure tous les drapeaux)
RTI Dépiler P puis PC depuis la pile (retour d'interruption)
CLC C := 0
SEC C := 1
CLD D := 0
SED D := 1
CLI I := 0
SEI I := 1
CLV V := 0 (pas de SEV)

Organisation de la mémoire

Le 6502 possède un espace d'adressage linéaire de 64 Ko (16 bits d'adresses, $0000 a $FFFF). Cet espace est divise en 256 pages de 256 octets chacune. Certaines pages ont des rôles particuliers imposes par le matériel.

Carte mémoire générale :

Adresse Page Contenu
$0000-$00FF Page 0 Page zéro (Zéro Page)
Accès rapide, pseudo-registres, pointeurs indirects
$0100-$01FF Page 1 Pile (Stack)
Utilisée par PHA/PLA, PHP/PLP, JSR/RTS, BRK/RTI, IRQ, NMI
$0200-$FFEF 2-254 Mémoire libre (RAM, ROM, E/S selon le système)
$FFF0-$FFF9 255 (généralement ROM, selon le système)
$FFFA-$FFFB 255 Vecteur NMI (adresse du gestionnaire NMI)
$FFFC-$FFFD 255 Vecteur RESET (adresse de démarrage)
$FFFE-$FFFF 255 Vecteur IRQ/BRK (adresse du gestionnaire)

Page zéro ($0000-$00FF) :

La page zéro est la région de mémoire la plus importante pour la programmation du 6502. Elle bénéficie de modes d'adressage spécifiques étant :

La page zéro est utilisée pour :

Modes d'adressage spécifiques a la page zéro :

  1. LDA $80         ; Zero Page          (2 octets, 3 cycles)
  2. LDA $80,X       ; Zero Page,X        (2 octets, 4 cycles)
  3. LDA ($80,X)     ; Indexed Indirect   (2 octets, 6 cycles)
  4. LDA ($80),Y     ; Indirect Indexed   (2 octets, 5 cycles*)

Pour comparaison, les équivalents en adressage absolu :

  1. LDA $0080       ; Absolute           (3 octets, 4 cycles)
  2. LDA $0080,X     ; Absolute,X         (3 octets, 4 cycles*)

(* : +1 cycle si le franchissement de page se produit)

Exemple de pointeur en page zéro :

  1. ; Entreposer un pointeur vers $8000 dans la page zero a $80-$81
  2. LDA #$00
  3. STA $80         ; poids faible a $80
  4. LDA #$80
  5. STA $81         ; poids fort a $81
  6. ; Utiliser le pointeur pour lire des donnees
  7. LDY #$00
  8. LDA ($80),Y     ; A = contenu de $8000 + Y

Sur de nombreux systèmes, une partie de la page zéro est réservée par le système d'exploitation ou le moniteur :

Page 1 - Pile ($0100-$01FF) :

La page 1 est entièrement dédiée a la pile. Le pointeur de pile (SP) est un registre de 8 bits qui est combine avec le préfixe fixe $01 pour former l'adresse 16 bits de pile.

Vecteurs d'interruption ($FFFA-$FFFF) :

Les 6 derniers octets de l'espace d'adressage contiennent les trois vecteurs d'interruption, entreposés en format little-endian (poids faible en premier) :

Adresse Vecteur Description
$FFFA-FB NMI Vector Adresse du gestionnaire NMI
$FFFC-FD RESET Vector Adresse de démarrage après RESET
$FFFE-FF IRQ/BRK Vector Adresse du gestionnaire IRQ et BRK

Ces vecteurs doivent pointer vers de la ROM ou de la mémoire contenant du code valide. Le processeur lit automatiquement le vecteur approprié lors d'un RESET, d'une NMI ou d'une IRQ/BRK.

Pas de séparation entre mémoire et entrée/sortie :

Le 6502 utilise un modèle d'entrées/sorties mappe en mémoire (memory-mapped I/O). Il n'y a PAS d'instructions d'entrée/sortie séparées (contrairement au Z80 avec IN/OUT ou au x86 avec IN/OUT). Les périphériques sont accédés par des lectures et écritures a des adresses mémoire spécifiques.

Exemples sur des systèmes courants :

Commodore 64 :

Adresse Description
$D000-$D3FF VIC-II (graphiques)
$D400-$D7FF SID (son)
$D800-$DBFF Mémoire couleur
$DC00-$DCFF CIA 1 (clavier, manette de jeux)
$DD00-$DDFF CIA 2 (port série, banque VIC)

Apple II :

Adresse Description
$C000-$C0FF Périphériques internes (clavier,...)
$C100-$C7FF ROM des cartes d'extension (fentes 1-7)

NES :

Adresse Description
$2000-$2007 PPU (graphiques)
$4000-$4017 APU (son) et entrée/sortie

Atari 2600 :

Adresse Description
$00-$7F TIA (Television Interface Adaptor)
$0280-$0297 RIOT (RAM-I/O-Timer)

La pile (Stack)

La pile du 6502 est une structure de données LIFO (Last In, First Out) implémentée en matériel dans la page 1 de la mémoire. Son fonctionnement est contrôle par le registre SP (Stack Pointer).

Emplacement physique :

Direction de croissance :

Format d'empilage (Push) :

Format de dépilage (Pull) :

Débordement de pile :

Utilisation de la pile par les interruptions :

Lors d'une interruption (IRQ, NMI) ou d'un BRK, le processeur empile automatiquement 3 octets dans cet ordre :

Puis il charge PC depuis le vecteur d'interruption approprié.

L'instruction RTI dépile dans l'ordre inverse :

Utilisation de la pile par JSR/RTS :

JSR empile l'adresse de retour MOINS 1 (2 octets) :

RTS dépile et ajoute 1 :

Techniques courantes avec la pile :

Sauvegarde/restauration de registres dans une sous-routine :

  1.   MaRoutine:
  2.      PHA             ; sauvegarder A
  3.      TXA
  4.      PHA             ; sauvegarder X
  5.      TYA
  6.      PHA             ; sauvegarder Y
  7.      ; ... code de la routine ...
  8.      PLA
  9.      TAY             ; restaurer Y
  10.      PLA
  11.      TAX             ; restaurer X
  12.      PLA             ; restaurer A
  13.      RTS

Passage de paramètres par la pile :

  1.   ; Empiler un parametre
  2. LDA #$42
  3. PHA
  4.   ; Appeler la routine
  5. JSR MaRoutine
  6.   ; Dans la routine, acceder au parametre :
  7. TSX
  8. LDA $0103,X     ; $0103 car : SP+1=retPCL, +2=retPCH,
  9. ;              +3=parametre

Résumé des registres

Registre Taille Description
A (Accumulateur) 8 bits Seul registre arithmétique/logique
X (Index X) 8 bits Registre d'index, modes (ZP,X) (ABS,X) (IND,X), transfert SP
Y (Index Y) 8 bits Registre d'index, modes (ZP,Y) (ABS,Y) (IND),Y
SP (Stack Pointer) 8 bits Pointeur de pile (page 1, $0100+SP)
PC (Program Counter) 16 bits Compteur programme
P (Processor Status) 8 bits Drapeaux : N V - B D I Z C
Total 5 registres de 8 bits + 1 de 16 bits

Comparaison avec d'autres processeurs 8 bits :

Aspect 6502 Z80 6800
Accumulateur A (8 bits) A (8 bits) A, B (8 bits)
Registres d'index X, Y (8 bits) IX, IY (16 bits) X (16 bits)
Registres généraux - B,C,D,E,H,L -
Pointeur de pile SP (8 bits) SP (16 bits) SP (16 bits)
Compteur programme PC (16 bits) PC (16 bits) PC (16 bits)
Drapeaux P (8 bits) F (8 bits) CC (8 bits)
Registre de rafraîchissement - R (7 bits) -
Registre d'interruption - I (8 bits) -
Jeu alternatif - AF', BC', etc. -
Taille pile 256 octets 64 Ko 64 Ko
Page zero Oui (256 octets) Non Non (Direct Page sur 6809)

Comparaison avec le Motorola 68000 :

Aspect 6502 68000
Largeur 8 bits 16/32 bits
Registres généraux A, X, Y D0-D7 (32 bits)
Registres d'adresses - A0-A7 (32 bits)
Pointeur de pile SP (8 bits) A7/USP/SSP (32b)
Compteur programme PC (16 bits) PC (32 bits)
Espace adressable 64 Ko 16 Mo
Endianness Little-endian Big-endian
Taille pile 256 octets Illimitee (RAM)
Modes d'adressage 13 14
Instructions 56 56+
Page zéro Oui Non


Dernière mise à jour : Mardi, le 6 décembre 2016