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 :
- Une ALU (Arithmetic Logic Unit) de 8 bits
- Un accumulateur de 8 bits (A), seul registre arithmétique
- Deux registres d'index de 8 bits (X et Y)
- Un pointeur de pile de 8 bits (SP), limitant la pile a 256 octets dans la page 1 ($0100-$01FF)
- Un compteur programme de 16 bits (PC)
- Un registre d'état de 8 bits (P) contenant les drapeaux
- Un pipeline simplifie a 2 étages (fetch / execute) permettant un chevauchement partiel entre le chargement de l'instruction suivante et l'exécution de l'instruction courante
- Un bus de données de 8 bits
- Un bus d'adresses de 16 bits (64 Ko adressables)
- Un contrôleur de bus synchrone cadence par une horloge externe (PHI0/PHI1/PHI2)
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 :
- Le mode BCD (Binary Coded Decimal) est disponible pour ADC et SBC quand le drapeau D est a 1. Dans ce mode, chaque quartet (4 bits) représente un chiffre décimal (0-9). Exemple : $42 représente le nombre décimal 42.
- Sur le 6502 NMOS original, les drapeaux N et Z ne sont pas correctement positionnes en mode BCD. Le 65C02 (CMOS) corrige ce comportement.
- Le Ricoh 2A03 (NES) n'implémente PAS le mode BCD; le drapeau D est ignore.
Exemples :
- LDA #$42 ; A = $42 (chargement immediat)
- LDA $80 ; A = contenu de l'adresse $0080 (page zero)
- LDA $1234 ; A = contenu de l'adresse $1234 (absolu)
- STA $0400 ; stocker A a l'adresse $0400
- ADC #$10 ; A = A + $10 + C
- AND #$0F ; masquer les 4 bits hauts (A = A AND $0F)
- ASL A ; decaler A a gauche (multiplication par 2)
- 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 :
- Page zéro indexe par X : LDA $80,X
- Absolu indexe par X : LDA $1234,X
- Indirect indexe par X : LDA ($80,X)
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 :
- Compteur de boucle
- Index pour parcourir des tableaux
- Initialisation du pointeur de pile (via TXS)
- Accès indirect indexe pre-indexe (Indexed Indirect)
Registre Y :
Modes d'adressage supportes :
- Page zéro indexe par Y : LDX $80,Y (uniquement LDX/STX)
- Absolu indexe par Y : LDA $1234,Y
- Indirect indexe par Y : LDA ($80),Y
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 :
- Compteur de boucle
- Index pour parcourir des tableaux
- Accès indirect indexe post-indexe (Indirect Indexed)
- Compteur secondaire quand X est déjà utilise
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 |
- * LDX $ZP,Y et STX $ZP,Y sont les seules instructions supportant le mode page zéro indexe par Y.
- ** LDY $ZP,X et STY $ZP,X utilisent le mode page zéro indexe par X pour LDY/STY.
Exemples :
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 :
- La pile est située en page 1 de la mémoire, aux adresses $0100 a $01FF
- L'adresse effective de pile est toujours $0100 + SP
- L'octet de poids fort de l'adresse est toujours $01 (câble en dur)
Fonctionnement :
- La pile croit vers le bas (vers les adresses décroissantes)
- SP pointe vers le prochain emplacement libre (pas vers le dernier élément empile)
- Lors d'un PUSH : écriture a $0100+SP, puis SP := SP - 1
- Lors d'un PULL : SP := SP + 1, puis lecture de $0100+SP
- Le SP "wrappe" naturellement : si SP = $00 et qu'on empile, SP passe a $FF (pas de détection de débordement de pile)
Initialisation :
- Après un RESET, SP est initialise a $FD (convention commune)
- Le programmeur peut initialiser SP a n'importe quelle valeur via les instructions LDX / TXS :
- LDX #$FF ; X = $FF
- TXS ; SP = X = $FF (pile vide, sommet a $01FF)
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 :
- Avec 256 octets, la pile peut contenir au maximum :
- 128 adresses de retour (JSR utilise 2 octets chacune)
- 256 octets de données (PHA utilise 1 octet chacun)
- Ou une combinaison des deux
- Il n'y a pas de détection matérielle de débordement de pile
- Un débordement de pile écrasé silencieusement le début de la page 1 ($0100) et peut corrompre le programme
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 :
- Non accessible directement par les instructions de transfert (pas de "LDA PC" ou "STA PC")
- Automatiquement incremente lors du chargement des octets de l'instruction courante
- Modifie par les instructions de saut et de branchement :
- Initialise au démarrage (RESET) a partir du vecteur de réinitialisation :
| Instruction | Description |
|---|---|
| JMP | Saut absolu ou indirect (PC := adresse cible) |
| JSR | Appel de sous-routine (empile PC-1, PC := cible) |
| RTS | Retour de sous-routine (PC := depile + 1) |
| RTI | Retour d'interruption (PC := depile) |
| BCC, BCS, BEQ, BNE, BMI, BPL, BVC, BVS | Branchement conditionnel relatif (PC := PC + deplacement signe si condition vraie) |
|
PC_low := [$FFFC] PC_high := [$FFFD] |
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 :
- Les instructions de branchement conditionnel (Bxx) utilisent un déplacement signe de 8 bits (-128 a +127) relatif a l'adresse de l'instruction SUIVANT le branchement
- Portée effective : PC - 126 a PC + 129 (par rapport a l'adresse du branchement lui-même, qui fait 2 octets)
- Pour les sauts hors de cette portée, il faut utiliser JMP avec un branchement inverse :
- ; Au lieu de BEQ FarTarget (hors portee) :
- BNE Skip
- JMP FarTarget
- Skip:
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) :
- Mis a 1 si une addition (ADC) produit une retenue au-delà du bit 7, ou si une soustraction (SBC) ne produit PAS d'emprunt.
- Utilise par ADC/SBC pour l'arithmétique multi-octet :
- Reçoit le bit sortant lors des décalages et rotations :
- Positionne par CMP/CPX/CPY :
- C = 1 si registre >= opérande (comparaison non signée)
- C = 0 si registre < opérande
- Instructions de contrôle :
- IMPORTANT : Toujours initialiser C avant une séquence arithmétique :
Z (Zero, bit 1) :
- Mis a 1 si le résultat de la dernière opération est $00
- Mis a 0 sinon
- Positionne par la plupart des instructions : LDA, LDX, LDY, ADC, SBC, AND, ORA, EOR, ASL, LSR, ROL, ROR, INC, DEC, INX, INY, DEX, DEY, TAX, TAY, TXA, TYA, TSX, PLA, PLP, CMP, CPX, CPY, BIT
- N'est PAS modifie par : STA, STX, STY, PHA, PHP, TXS, CLC, SEC, CLD, SED, CLI, SEI, CLV, JMP, JSR, RTS, RTI, BRK, NOP, ni les branchements Bxx
I (Interrupt Disable, bit 2) :
- Quand I = 1, les interruptions IRQ sont masquées (ignorées)
- Quand I = 0, les interruptions IRQ sont autorisées
- Les NMI (Non-Maskable Interrupts) ne sont PAS affectées par I
- Mis a 1 automatiquement par le processeur :
- Au RESET
- Lors du traitement d'une IRQ
- Lors du traitement d'une NMI
- Lors de l'exécution de BRK
- Instructions de contrôle :
- Note : l'instruction PLP (restaurer P depuis la pile) peut aussi modifier I
D (Decimal, bit 3) :
- Quand D = 1, ADC et SBC opèrent en mode BCD (Binary Coded Decimal) au lieu du mode binaire
- En mode BCD, chaque octet représente deux chiffres décimaux :
- $09 + $01 = $10 (et non $0A comme en binaire)
- $99 + $01 = $00 avec C = 1 (dépassement BCD)
- Instructions de contrôle :
- Le mode BCD est utile pour les affichages de scores, les calculs financiers et toute application ou une représentation décimale exacte est nécessaire
- IMPORTANT : Le drapeau D n'est PAS automatiquement remis a 0 après un RESET sur le 6502 NMOS. Il est bonne pratique d'exécuter CLD au début de tout programme et dans les gestionnaires d'interruption.
- Sur le 65C02 (CMOS), D est remis a 0 automatiquement après un RESET, un IRQ, un NMI et un BRK.
- Sur le Ricoh 2A03/2A07 (NES), le mode BCD est désactive en permanence (D n'a aucun effet).
B (Break, bit 4) :
- Le drapeau B n'existe pas physiquement dans le registre P
- Il n'est visible que dans la copie de P empilée sur la pile :
- * PHP et BRK empilent P avec B = 1
- * IRQ et NMI empilent P avec B = 0
- Permet au gestionnaire d'interruption de distinguer un BRK (interruption logicielle) d'une IRQ (interruption matérielle), car les deux utilisent le même vecteur ($FFFE)
- Vérification typique dans un gestionnaire d'interruption :
V (Overflow, bit 6) :
- Mis a 1 si une opération ADC ou SBC produit un résultat incorrect en arithmétique signée (complément a deux)
- Concrètement, V = 1 quand :
- ADC : deux opérandes positifs donnent un résultat négatif
- ADC : deux opérandes négatifs donnent un résultat positif
- SBC : équivalent (via la soustraction en complément a 2)
- L'instruction BIT positionne V avec le bit 6 de l'opérande me moire (utile pour tester un registre d'état matériel)
- Instruction de contrôle :
- CLV : V := 0 (Clear Overflow)
- Il n'y a PAS d'instruction "SEV" (Set Overflow) sur le 6502
- Certains systèmes utilisent la ligne SO (Set Overflow) du 6502, une broche d'entrée mettant V a 1 sur un front descendant (utilisée par le Commodore 1541 pour la synchronisation du lecteur de disquettes)
N (Negative, bit 7) :
- Copie du bit 7 du résultat de la dernière opération
- En arithmétique signée (complément a deux), bit 7 = 1 signifie que la valeur est négative
- Intervalle des valeurs signées sur 8 bits :
- $00 a $7F = 0 a +127
- $80 a $FF = -128 a -1
- L'instruction BIT positionne N avec le bit 7 de l'opérande mémoire (comme V est positionne avec le bit 6)
- Positionne par les mêmes instructions que Z
Bit 5 (inutilisé) :
- Toujours lu comme 1 lors d'un PHP ou d'un empilage de P
- N'a aucune fonction et ne peut pas être modifié
- Parfois appelé "expansion bit" dans la documentation originale de MOS Technology
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 :
- Plus rapides : 3 cycles au lieu de 4 pour un accès absolu
- Plus compacts : 2 octets d'instruction au lieu de 3
La page zéro est utilisée pour :
- Entreposer des variables fréquemment accédées
- Entreposer des pointeurs de 16 bits pour l'adressage indirect (chaque pointeur occupe 2 octets consécutifs en page zéro)
- Servir de pseudo-registres supplémentaires compensant le faible nombre de registres du processeur
Modes d'adressage spécifiques a la page zéro :
Pour comparaison, les équivalents en adressage absolu :
(* : +1 cycle si le franchissement de page se produit)
Exemple de pointeur en page zéro :
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 :
- Apple II : $00-$4F réservés par le moniteur et Applesoft
- Commodore 64 : $00-$01 réservés (port du 6510), $02-$8F utilises par le BASIC et le Kernal
- Atari 800 : $00-$7F réservés par le système
- NES : toute la page zéro est disponible pour le programme
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 :
| 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) | ||
| Adresse | Description |
|---|---|
| $2000-$2007 | PPU (graphiques) |
| $4000-$4017 | APU (son) et entrée/sortie |
| 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 :
- Adresses $0100 a $01FF (page 1, 256 octets)
Direction de croissance :
- La pile croit vers le bas (des adresses hautes vers les basses). SP commence typiquement a $FF (sommet de la page 1) et décroît a chaque empilage.
Format d'empilage (Push) :
- 1. Écrire la donnée a l'adresse $0100 + SP
- 2. Décrémenter SP (SP := SP - 1)
Format de dépilage (Pull) :
- 1. Incrémenter SP (SP := SP + 1)
- 2. Lire la donnée a l'adresse $0100 + SP
Débordement de pile :
- Il n'y a aucune détection matérielle de débordement
- Si SP passe de $00 a $FF (empilage excessif), la pile "wrappe" et les anciennes données sont écrasées
- Si SP passe de $FF a $00 (dépilage excessif), des données invalides sont lues
- Le programmeur est responsable de gérer la profondeur 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 :
- 1. PC poids fort (PCH) → [$0100+SP], SP := SP - 1
- 2. PC poids faible (PCL) → [$0100+SP], SP := SP - 1
- 3. Registre P (status) → [$0100+SP], SP := SP - 1
Puis il charge PC depuis le vecteur d'interruption approprié.
L'instruction RTI dépile dans l'ordre inverse :
- 1. P ← [$0100+SP+1], SP := SP + 1
- 2. PCL ← [$0100+SP+1], SP := SP + 1
- 3. PCH ← [$0100+SP+1], SP := SP + 1
Utilisation de la pile par JSR/RTS :
JSR empile l'adresse de retour MOINS 1 (2 octets) :
- 1. PCH de (adresse de retour - 1) → [$0100+SP], SP := SP - 1
- 2. PCL de (adresse de retour - 1) → [$0100+SP], SP := SP - 1
RTS dépile et ajoute 1 :
- 1. PCL ← [$0100+SP+1], SP := SP + 1
- 2. PCH ← [$0100+SP+1], SP := SP + 1
- 3. PC := PC + 1
Techniques courantes avec la pile :
Sauvegarde/restauration de registres dans une sous-routine :
- MaRoutine:
- PHA ; sauvegarder A
- TXA
- PHA ; sauvegarder X
- TYA
- PHA ; sauvegarder Y
- ; ... code de la routine ...
- PLA
- TAY ; restaurer Y
- PLA
- TAX ; restaurer X
- PLA ; restaurer A
- RTS
Passage de paramètres par la pile :
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 |