Section courante

A propos

Section administrative du site

Ensemble d'instructions (Opcodes)

Le 6502 possède un ensemble de 56 instructions officielles. Malgré ce nombre réduit, le microprocesseur est capable de réaliser des programmes complets et performants grâce a l'utilisation combinée de ses modes d'adressage variés.

Chaque instruction est codée sur un octet (opcode). Selon le mode d'adressage, l'instruction complète occupe 1, 2 ou 3 octets en mémoire. Le nombre total d'opcodes valides est de 151 (sur 256 combinaisons possibles).

L'ensemble d'instructions se divise en catégories :

Conventions de notation utilisées dans cette section :

Notation Description
A Accumulateur
X Registre d'index X
Y Registre d'index Y
SP Pointeur de pile
PC Compteur programme
P Registre d'état du processeur
M Contenu de l'emplacement mémoire adresse
nn Valeur 8 bits (opérande immédiat ou adresse page zéro)
nnnn Valeur 16 bits (adresse absolue)
[CCR] Drapeaux affectes (N, V, -, B, D, I, Z, C)
-> ou → Affectation (résultat vers destination)
$ Préfixe hexadécimal
# Préfixe immédiat (la valeur elle-même, pas une adresse)

Pour chaque instruction, les informations suivantes sont données :

Instructions de transfert de données

Ces instructions copient des données entre les registres et la mémoire, ou entre les registres eux-mêmes.

LDA - Load Accumulator (Charger l'accumulateur)

Charge une valeur dans l'accumulateur A.

Opération : A ← M

Drapeaux affectes : N, Z

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat LDA #$nn $A9 2 2
Page zéro LDA $nn $A5 2 3
Page zero,X LDA $nn,X $B5 2 4
Absolu LDA $nnnn $AD 3 4
Absolu,X LDA $nnnn,X $BD 3 4(+1)
Absolu,Y LDA $nnnn,Y $B9 3 4(+1)
(Indirect,X) LDA ($nn,X) $A1 2 6
(Indirect),Y LDA ($nn),Y $B1 2 5(+1)

(+1) = +1 cycle si franchissement de page (page boundary crossing)

Exemples :

  1. LDA #$42          ; A := $42 (immediat)
  2. LDA $80           ; A := contenu de l'adresse $0080
  3. LDA $2000         ; A := contenu de l'adresse $2000
  4. LDA $2000,X       ; A := contenu de l'adresse $2000+X
  5. LDA ($80),Y       ; A := contenu de l'adresse [($80)]+Y

LDX - Load X Register (Charger le registre X)

Charge une valeur dans le registre d'index X.

Opération : X ← M

Drapeaux affectes : N, Z

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat LDX #$nn $A2 2 2
Page zéro LDX $nn $A6 2 3
Page zéro,Y LDX $nn,Y $B6 2 4
Absolu LDX $nnnn $AE 3 4
Absolu,Y LDX $nnnn,Y $BE 3 4(+1)

Exemples :

  1. LDX #$00          ; X := 0
  2. LDX $80           ; X := contenu de $0080
  3. LDX Table,Y       ; X := contenu de Table+Y

Remarque :

LDY - Load Y Register (Charger le registre Y)

Charge une valeur dans le registre d'index Y.

Opération : Y ← M

Drapeaux affectes : N, Z

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat LDY #$nn $A0 2 2
Page zero LDY $nn $A4 2 3
Page zero,X LDY $nn,X $B4 2 4
Absolu LDY $nnnn $AC 3 4
Absolu,X LDY $nnnn,X $BC 3 4(+1)

Exemples :

  1. LDY #$09          ; Y := 9
  2. LDY $80,X         ; Y := contenu de ($80+X) AND $FF
  3. LDY Table,X       ; Y := contenu de Table+X

STA - Store Accumulator (Entreposer l'accumulateur)

Entrepose le contenu de l'accumulateur A en mémoire.

Opération : M ← A

Drapeaux affectes : aucun

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Page zero STA $nn $85 2 3
Page zero,X STA $nn,X $95 2 4
Absolu STA $nnnn $8D 3 4
Absolu,X STA $nnnn,X $9D 3 5
Absolu,Y STA $nnnn,Y $99 3 5
(Indirect,X) STA ($nn,X) $81 2 6
(Indirect),Y STA ($nn),Y $91 2 6

Exemples :

  1. STA $80           ; stocker A a l'adresse $0080
  2. STA $2000         ; stocker A a l'adresse $2000
  3. STA $0400,X       ; stocker A a l'adresse $0400+X
  4. STA ($80),Y       ; stocker A a l'adresse [($80)]+Y

Remarques :

STX - Store X Register (Entreposer le registre X)

Entrepose le contenu du registre X en mémoire.

Opération : M ← X

Drapeaux affectes : aucun

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Page zéro STX $nn $86 2 3
Page zero,Y STX $nn,Y $96 2 4
Absolu STX $nnnn $8E 3 4

Exemples :

  1. STX $80           ; stocker X a l'adresse $0080
  2. STX $2000         ; stocker X a l'adresse $2000

STY - Store Y Register (Entreposer le registre Y)

Entrepose le contenu du registre Y en mémoire.

Opération : M ← Y

Drapeaux affectes : aucun

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Page zéro STY $nn $84 2 3
Page zero,X STY $nn,X $94 2 4
Absolu STY $nnnn $8C 3 4

Exemples :

  1. STY $80           ; entreposer Y a l'adresse $0080
  2. STY $2000         ; entreposer Y a l'adresse $2000

Transferts entre registres

Ces instructions copient une valeur d'un registre vers un autre. Elles n'ont pas d'opérande (mode implicite), occupent 1 octet et s'exécutent en 2 cycles.

Instruction Opération
TAX ($AA) A → X Drapeaux : N, Z
TAY ($A8) A → Y Drapeaux : N, Z
TXA ($8A) X → A Drapeaux : N, Z
TYA ($98) Y → A Drapeaux : N, Z
TSX ($BA) SP → X Drapeaux : N, Z
TXS ($9A) X → SP Drapeaux : aucun

Exemples :

  1. ; Copier A dans X pour utiliser X comme index
  2. TAX               ; X := A
  3.  
  4. ; Sauvegarder le pointeur de pile dans X
  5. TSX               ; X := SP
  6.  
  7. ; Initialiser le pointeur de pile
  8. LDX #$FF
  9. TXS               ; SP := $FF (pile pleine)
  10.  
  11. ; Echanger A et X (pas d'instruction directe)
  12. TAX               ; sauver A dans X
  13. ; ... (utiliser A pour autre chose)
  14. TXA               ; restaurer A depuis X

Remarques :

Instructions arithmétiques

Le 6502 dispose d'instructions d'addition et de soustraction avec retenue, ainsi que d'instructions d'incrément et de décrément.

ADC - Add with Carry (Addition avec retenue)

Ajoute la valeur de l'opérande et du drapeau de retenue (C) a l'accumulateur.

Opération : A ← A + M + C

Drapeaux affectes : N, V, Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat ADC #$nn $69 2 2
Page zéro ADC $nn $65 2 3
Page zero,X ADC $nn,X $75 2 4
Absolu ADC $nnnn $6D 3 4
Absolu,X ADC $nnnn,X $7D 3 4(+1)
Absolu,Y ADC $nnnn,Y $79 3 4(+1)
(Indirect,X) ADC ($nn,X) $61 2 6
(Indirect),Y ADC ($nn),Y $71 2 5(+1)

Exemples :

  1. ; Addition simple 8 bits : A = $30 + $10
  2. CLC               ; TOUJOURS effacer C avant une addition
  3. LDA #$30
  4. ADC #$10          ; A = $40, C = 0
  5.  
  6. ; Addition 16 bits : resultat = $80/$81 + $82/$83
  7. CLC               ; effacer la retenue
  8. LDA $80           ; poids faible de la 1ere valeur
  9. ADC $82           ; + poids faible de la 2e valeur
  10. STA $84           ; stocker le poids faible du resultat
  11. LDA $81           ; poids fort de la 1ere valeur
  12. ADC $83           ; + poids fort + retenue de l'addition precedente
  13. STA $85           ; stocker le poids fort du resultat
  14.  
  15. ; Addition 8 bits avec retenue entrante
  16. ; (par ex. pour une chaine d'additions multi-precision)
  17. ADC $90           ; A = A + [$90] + C

Mode décimal (BCD) :

  1. SED               ; activer le mode BCD
  2. CLC
  3. LDA #$15          ; 15 en BCD
  4. ADC #$27          ; + 27 en BCD
  5. ; A = $42 (42 en BCD), C = 0
  6. CLD               ; desactiver le mode BCD

Remarques :

SBC - Subtract with Carry (Soustraction avec retenue)

Soustrait la valeur de l'opérande et le complément du drapeau de retenue (borrow) de l'accumulateur.

Opération : A ← A - M - NOT(C)

(équivalent a : A ← A - M - (1 - C))

Drapeaux affectes : N, V, Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat SBC #$nn $E9 2 2
Page zero SBC $nn $E5 2 3
Page zero,X SBC $nn,X $F5 2 4
Absolu SBC $nnnn $ED 3 4
Absolu,X SBC $nnnn,X $FD 3 4(+1)
Absolu,Y SBC $nnnn,Y $F9 3 4(+1)
(Indirect,X) SBC ($nn,X) $E1 2 6
(Indirect),Y SBC ($nn),Y $F1 2 5(+1)

Exemples :

  1. ; Soustraction simple 8 bits : A = $50 - $10
  2. SEC               ; TOUJOURS positionner C avant une soustraction
  3. LDA #$50
  4. SBC #$10          ; A = $40, C = 1 (pas d'emprunt)
  5.  
  6. ; Soustraction 16 bits : resultat = $80/$81 - $82/$83
  7. SEC               ; positionner la retenue (pas d'emprunt)
  8. LDA $80           ; poids faible de la 1ere valeur
  9. SBC $82           ; - poids faible de la 2e valeur
  10. STA $84           ; stocker le poids faible du resultat
  11. LDA $81           ; poids fort de la 1ere valeur
  12. SBC $83           ; - poids fort - emprunt eventuel
  13. STA $85           ; stocker le poids fort du resultat
  14.  
  15. ; Negation (complement a deux) : A = 0 - A
  16. EOR #$FF          ; complement a un
  17. CLC
  18. ADC #$01          ; + 1 = complement a deux

Remarques :

INC - Increment Memory (Incrementer la memoire)

Incrémente de 1 la valeur a l'emplacement mémoire spécifié.

Opération : M ← M + 1

Drapeaux affectes : N, Z

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Page zéro INC $nn $E6 2 5
Page zero,X INC $nn,X $F6 2 6
Absolu INC $nnnn $EE 3 6
Absolu,X INC $nnnn,X $FE 3 7

Exemples :

  1. INC $80           ; incrementer le contenu de $0080
  2. INC $2000         ; incrementer le contenu de $2000
  3. INC $2000,X       ; incrementer le contenu de $2000+X

Remarque :

INX - Increment X Register (Incrémenter X)

Incrémente de 1 le registre X.

Opération : X ← X + 1

Drapeaux affectes : N, Z

Opcode Taille Cycles
$E8 1 octet 2

Exemple :

  1. INX               ; X := X + 1

INY - Increment Y Register (Incrementer Y)

Incrémente de 1 le registre Y.

Opération : Y ← Y + 1

Drapeaux affectes : N, Z

Opcode Taille Cycles
$C8 1 octet 2

Exemple :

  1. INY               ; Y := Y + 1

DEC - Decrement Memory (Décrémenter la mémoire)

Décrementé de 1 la valeur à l'emplacement mémoire spécifié.

Opération : M ← M - 1

Drapeaux affectes : N, Z

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Page zero DEC $nn $C6 2 5
Page zero,X DEC $nn,X $D6 2 6
Absolu DEC $nnnn $CE 3 6
Absolu,X DEC $nnnn,X $DE 3 7

Exemples :

  1. DEC $80           ; decrementer le contenu de $0080
  2. DEC Compteur      ; decrementer la variable Compteur

Remarque :

DEX - Decrement X Register (Decrementer X)

Décrémente de 1 le registre X.

Operation : X ← X - 1

Drapeaux affectes : N, Z

Opcode Taille Cycles
$CA 1 octet 2

Exemple :

  1.     ; Boucle simple avec X comme compteur
  2.     LDX #$10          ; X := 16
  3.   Boucle:
  4.     DEX               ; X := X - 1
  5.     BNE Boucle        ; boucler tant que X != 0

DEY - Decrement Y Register (Décrémenter Y)

Décrementé de 1 le registre Y.

Opération : Y ← Y - 1

Drapeaux affectes : N, Z

Opcode Taille Cycles
$88 1 octet 2

Exemple :

  1.     ; Boucle simple avec Y comme compteur
  2.     LDY #$08          ; Y := 8
  3.   Boucle:
  4.     DEY               ; Y := Y - 1
  5.     BNE Boucle        ; boucler tant que Y != 0

Instructions logiques

Le 6502 dispose de trois opérations logiques bit a bit qui opèrent sur l'accumulateur A.

AND - Logical AND (ET logique)

Effectue un ET logique bit a bit entre l'accumulateur et l'opérande.

Opération : A ← A AND M

Drapeaux affectes : N, Z

Table de vérité :

A M Résultat
0 0 0
0 1 0
1 0 0
1 1 1

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat AND #$nn $29 2 2
Page zero AND $nn $25 2 3
Page zero,X AND $nn,X $35 2 4
Absolu AND $nnnn $2D 3 4
Absolu,X AND $nnnn,X $3D 3 4(+1)
Absolu,Y AND $nnnn,Y $39 3 4(+1)
(Indirect,X) AND ($nn,X) $21 2 6
(Indirect),Y AND ($nn),Y $31 2 5(+1)

Exemples :

  1. AND #$0F          ; masquer les 4 bits de poids fort (garder 0-F)
  2. AND #$F0          ; masquer les 4 bits de poids faible
  3. AND #%11110000    ; equivalent en binaire
  4. AND #$FE          ; effacer le bit 0

Utilisation typique :

ORA - Logical Inclusive OR (OU inclusif logique)

Effectue un OU logique bit a bit entre l'accumulateur et l'opérande.

Opération : A ← A OR M

Drapeaux affectes : N, Z

Table de vérité :

A M Résultat
0 0 0
0 1 1
1 0 1
1 1 1

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat ORA #$nn $09 2 2
Page zero ORA $nn $05 2 3
Page zero,X ORA $nn,X $15 2 4
Absolu ORA $nnnn $0D 3 4
Absolu,X ORA $nnnn,X $1D 3 4(+1)
Absolu,Y ORA $nnnn,Y $19 3 4(+1)
(Indirect,X) ORA ($nn,X) $01 2 6
(Indirect),Y ORA ($nn),Y $11 2 5(+1)

Exemples :

  1. ORA #$80          ; forcer le bit 7 a 1
  2. ORA #$01          ; forcer le bit 0 a 1
  3. ORA #%00001111    ; forcer les 4 bits de poids faible a 1

Utilisation typique :

EOR - Exclusive OR (OU exclusif logique)

Effectue un OU exclusif (XOR) bit a bit entre l'accumulateur et l'opérande.

Opération : A ← A XOR M

Drapeaux affectes : N, Z

Table de vérité :

A M Résultat
0 0 0
0 1 1
1 0 1
1 1 0

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat EOR #$nn $49 2 2
Page zero EOR $nn $45 2 3
Page zero,X EOR $nn,X $55 2 4
Absolu EOR $nnnn $4D 3 4
Absolu,X EOR $nnnn,X $5D 3 4(+1)
Absolu,Y EOR $nnnn,Y $59 3 4(+1)
(Indirect,X) EOR ($nn,X) $41 2 6
(Indirect),Y EOR ($nn),Y $51 2 5(+1)

Exemples :

  1. EOR #$FF          ; inverser tous les bits (complement a 1)
  2. EOR #$80          ; inverser le bit 7 (changer le signe)
  3. EOR #$01          ; inverser le bit 0 (basculer un flag)

Utilisation typique :

Instructions de décalage et rotation

Ces instructions décalent ou font tourner les bits d'un octet vers la gauche ou la droite. Elles peuvent opérer sur l'accumulateur A ou directement sur un emplacement mémoire.

ASL - Arithmetic Shift Left (Décalage arithmétique a gauche)

Décale tous les bits d'une position vers la gauche. Le bit 7 sort dans C et un 0 entre dans le bit 0.

Opération : C ← [76543210] ← 0

Drapeaux affectes : N, Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Accumulateur ASL A $0A 1 2
Page zero ASL $nn $06 2 5
Page zero,X ASL $nn,X $16 2 6
Absolu ASL $nnnn $0E 3 6
Absolu,X ASL $nnnn,X $1E 3 7

Exemples :

  1. ASL A             ; A = A * 2 (decalage a gauche)
  2. ASL $80           ; contenu de $0080 *= 2
  3. ; Multiplier A par 8 :
  4. ASL A             ; A * 2
  5. ASL A             ; A * 4
  6. ASL A             ; A * 8

LSR - Logical Shift Right (Décalage logique a droite)

Décale tous les bits d'une position vers la droite. Un 0 entre dans le bit 7 et le bit 0 sort dans C.

Opération : 0 → [76543210] → C

Drapeaux affectes : N (toujours 0), Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Accumulateur LSR A $4A 1 2
Page zero LSR $nn $46 2 5
Page zero,X LSR $nn,X $56 2 6
Absolu LSR $nnnn $4E 3 6
Absolu,X LSR $nnnn,X $5E 3 7

Exemples :

  1. LSR A             ; A = A / 2 (division entiere non signee)
  2. ; Diviser A par 4 :
  3. LSR A             ; A / 2
  4. LSR A             ; A / 4
  5.  
  6. ; Tester le bit 0 de A :
  7. LSR A             ; bit 0 -> C
  8. BCS BitEstUn      ; brancher si le bit 0 etait 1

ROL - Rotate Left (Rotation a gauche via C)

Fait tourner tous les bits d'une position vers la gauche a travers le drapeau C. Le bit 7 sort dans C et l'ancien C entre dans le bit 0.

Opération : C ← [76543210] ← C

Drapeaux affectes : N, Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Accumulateur ROL A $2A 1 2
Page zero ROL $nn $26 2 5
Page zero,X ROL $nn,X $36 2 6
Absolu ROL $nnnn $2E 3 6
Absolu,X ROL $nnnn,X $3E 3 7

Exemples :

  1. ; Rotation 16 bits a gauche de la valeur $80/$81
  2. ASL $80           ; decaler le poids faible, bit 7 -> C
  3. ROL $81           ; rotation du poids fort, C -> bit 0
  4.  
  5. ; Lecture serie bit par bit dans C
  6. ROL A             ; injecter C dans le bit 0, bit 7 -> C

ROR - Rotate Right (Rotation a droite via C)

Fait tourner tous les bits d'une position vers la droite a travers le drapeau C. Le bit 0 sort dans C et l'ancien C entre dans le bit 7.

Drapeaux affectes : N, Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Accumulateur ROR A $6A 1 2
Page zero ROR $nn $66 2 5
Page zero,X ROR $nn,X $76 2 6
Absolu ROR $nnnn $6E 3 6
Absolu,X ROR $nnnn,X $7E 3 7

Exemples :

  1. ; Rotation 16 bits a droite de la valeur $80/$81
  2. LSR $81           ; decaler le poids fort, bit 0 -> C
  3. ROR $80           ; rotation du poids faible, C -> bit 7
  4.  
  5. ; Division signee par 2 (conserver le signe)
  6. CMP #$80          ; copier le bit 7 (signe) dans C
  7. ROR A             ; diviser par 2 en conservant le signe

Note historique : L'instruction ROR n'existait pas dans les premières révisions du 6502 (avant juin 1976). Elle a été ajoutée plus tard. Les premières documentations de MOS Technology ne la mentionnaient pas, et elle fonctionnait de manière erratique sur les premiers exemplaires du processeur.

Instructions de comparaison

Ces instructions comparent un registre avec une valeur en mémoire en effectuant une soustraction interne sans modifier le registre. Seuls les drapeaux sont affectes.

CMP - Compare Accumulator (Comparer avec A)

Compare l'accumulateur avec la valeur en mémoire.

Opération : A - M (résultat non conserve)

Drapeaux affectes : N, Z, C

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat CMP #$nn $C9 2 2
Page zero CMP $nn $C5 2 3
Page zero,X CMP $nn,X $D5 2 4
Absolu CMP $nnnn $CD 3 4
Absolu,X CMP $nnnn,X $DD 3 4(+1)
Absolu,Y CMP $nnnn,Y $D9 3 4(+1)
(Indirect,X) CMP ($nn,X) $C1 2 6
(Indirect),Y CMP ($nn),Y $D1 2 5(+1)

Exemples et idiomes :

  1. ; Tester si A = $42
  2. CMP #$42
  3. BEQ Egal          ; brancher si A = $42
  4.  
  5. ; Tester si A < $20 (non signe)
  6. CMP #$20
  7. BCC Inferieur     ; brancher si A < $20
  8.  
  9. ; Tester si A >= $80 (non signe)
  10. CMP #$80
  11. BCS SupOuEgal     ; brancher si A >= $80
  12.  
  13. ; Tester si A est dans la plage 'A'-'Z'
  14. CMP #'A'
  15. BCC PasLettre     ; A < 'A'
  16. CMP #'Z'+1
  17. BCS PasLettre     ; A > 'Z'
  18. ; Ici, A est une lettre majuscule

CPX - Compare X Register (Comparer avec X)

Compare le registre X avec la valeur en mémoire.

Opération : X - M (résultat non conserve)

Drapeaux affectes : N, Z, C (mêmes règles que CMP)

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat CPX #$nn $E0 2 2
Page zero CPX $nn $E4 2 3
Absolu CPX $nnnn $EC 3 4

Exemples :

  1. CPX #$10
  2. BEQ XEstSeize     ; brancher si X = 16
  3. CPX #$00
  4. BEQ XEstZero      ; brancher si X = 0

CPY - Compare Y Register (Comparer avec Y)

Compare le registre Y avec la valeur en mémoire.

Opération : Y - M (résultat non conserve)

Drapeaux affectes : N, Z, C (mêmes règles que CMP)

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Immediat CPY #$nn $C0 2 2
Page zero CPY $nn $C4 2 3
Absolu CPY $nnnn $CC 3 4

Exemples :

  1. CPY #$18          ; comparer Y avec 24
  2. BCS SupOuEgal     ; brancher si Y >= 24

BIT - Test Bits (Test de bits)

Teste des bits en mémoire contre l'accumulateur sans modifier ni A ni M. C'est une instruction unique positionnant trois drapeaux de manières différentes.

Opération :

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Page zero BIT $nn $24 2 3
Absolu BIT $nnnn $2C 3 4

Exemples :

  1.     ; Tester si le bit 7 d'un registre materiel est positionne
  2.     BIT $D011         ; lire le registre VIC-II
  3.     BMI BitSept       ; brancher si bit 7 = 1 (N = bit 7 de M)
  4.  
  5.     ; Tester si le bit 6 est positionne
  6.     BIT $D011
  7.     BVS BitSix        ; brancher si bit 6 = 1 (V = bit 6 de M)
  8.  
  9.     ; Tester si certains bits sont a 1 dans un registre
  10.     LDA #%00001100    ; masque : bits 2 et 3
  11.     BIT Registre      ; tester
  12.     BNE AuMoinsUnBit  ; au moins un des bits 2 ou 3 est a 1
  13.  
  14.     ; Attendre qu'un peripherique soit pret (polling)
  15.   Attendre:
  16.     BIT StatutPerif   ; tester le registre de statut
  17.     BPL Attendre      ; boucler tant que bit 7 = 0

Remarques :

Instructions de branchement

Les instructions de branchement effectuent un saut relatif conditionnel. Elles testent un drapeau du registre d'état et, si la condition est vraie, ajoutent un déplacement signe de 8 bits au compteur programme.

Toutes les instructions de branchement :

BCC - Branch if Carry Clear (Brancher si C = 0)

Branche si le drapeau de retenue est efface.

Opcode : $90

Utilisation : après CMP/CPX/CPY pour tester "inferieur a" (comparaison non signée)

Exemple :

  1. CMP #$80
  2. BCC InferieurA128 ; brancher si A < $80

BCS - Branch if Carry Set (Brancher si C = 1)

Branche si le drapeau de retenue est positionne.

Opcode : $B0

Utilisation : après CMP/CPX/CPY pour tester "supérieur ou égal" (comparaison non signée)

Exemple :

  1. CMP #$80
  2. BCS SupOuEgalA128 ; brancher si A >= $80

BEQ - Branch if Equal (Brancher si Z = 1)

Branche si le drapeau zéro est positionne (résultat égal à zéro).

Opcode : $F0

Utilisation : après CMP pour tester "égal a", après LDA/LDX/LDY pour tester si la valeur chargée est zéro

Exemples :

  1. CMP #'A'
  2. BEQ EstUnA        ; brancher si A = 'A'
  3.  
  4. LDA $80
  5. BEQ EstZero       ; brancher si le contenu de $80 est 0
  6.  
  7. DEX
  8. BEQ XEstZero      ; brancher si X est devenu 0

BNE - Branch if Not Equal (Brancher si Z = 0)

Branche si le drapeau zéro est efface (résultat non nul).

Opcode : $D0

Utilisation : après CMP pour tester "différent de", comme condition de boucle (compteur != 0)

Exemples :

  1.     ; Boucle standard avec compteur X
  2.     LDX #$10
  3.   Boucle:
  4.     ; ... code de la boucle ...
  5.     DEX
  6.     BNE Boucle        ; boucler tant que X != 0
  7.  
  8.     CMP #$0D
  9.     BNE PasReturn     ; brancher si A != $0D (retour chariot)

BMI - Branch if Minus (Brancher si N = 1)

Branche si le drapeau négatif est positionne (bit 7 du résultat est 1).

Opcode : $30

Utilisation : tester le signe d'une valeur, tester le bit 7

Exemples :

  1. LDA Temperature
  2. BMI Negatif       ; brancher si la temperature est negative
  3.  
  4. BIT $D011
  5. BMI Pret          ; brancher si bit 7 du registre = 1

BPL - Branch if Plus (Brancher si N = 0)

Branche si le drapeau négatif est efface (bit 7 du résultat est 0).

Opcode : $10

Utilisation : tester le signe d'une valeur, polling de périphériques

Exemples :

  1.     ; Attendre que le bit 7 d'un registre passe a 1
  2.   Attendre:
  3.     BIT Registre
  4.     BPL Attendre      ; boucler tant que bit 7 = 0
  5.  
  6.     LDA Valeur
  7.     BPL Positif       ; brancher si >= 0 (en signe)

BVC - Branch if Overflow Clear (Brancher si V = 0)

Branche si le drapeau de débordement est efface.

Opcode : $50

Utilisation : rarement utilise, principalement pour l'arithmétique signée

Exemple :

  1. ADC Valeur
  2. BVC PasDebordement ; brancher si pas de débordement signe

BVS - Branch if Overflow Set (Brancher si V = 1)

Branche si le drapeau de débordement est positionne.

Opcode : $70

Utilisation : détection de débordement en arithmétique signée, lecture du pin SO (Set Overflow) de certains périphériques

Exemple :

  1. ADC Valeur
  2. BVS Debordement   ; brancher si debordement signe

Remarques générales sur les branchements :

Instructions de saut et d'appel

Ces instructions modifient le compteur programme (PC) pour effectuer des sauts inconditionnels ou des appels de sous-programmes.

JMP - Jump (Saut inconditionnel)

Charge une nouvelle adresse dans le compteur programme.

Opération : PC ← adresse

Drapeaux affectes : aucun

Modes d'adressage :

Mode Syntaxe Opcode Octets Cycles
Absolu JMP $nnnn $4C 3 3
Indirect JMP ($nnnn) $6C 3 5

Exemples :

  1. JMP $C000         ; sauter a l'adresse $C000
  2. JMP Suite         ; sauter a l'etiquette Suite
  3. JMP ($FFFC)       ; saut indirect via le vecteur RESET
  4. JMP (VecteurJmp)  ; saut indirect via un pointeur en memoire

JSR - Jump to Subroutine (Appel de sous-programme)

Empile l'adresse de retour (PC - 1) sur la pile, puis saute a l'adresse spécifiée.

Operation : PUSH (PC - 1), PC ← adresse

(PC - 1 car le 6502 empile l'adresse du DERNIER octet de l'instruction JSR, pas l'adresse de l'instruction suivante. RTS ajoutera 1 pour obtenir la bonne adresse de retour.)

Drapeaux affectes : aucun

Mode d'adressage :

Mode Syntaxe Opcode Octets Cycles
Absolu JSR $nnnn $20 3 6

Exemples :

  1. JSR SousRoutine   ; appeler SousRoutine
  2. JSR $FFD2         ; appeler CHROUT du Kernal C64

Détail de l'empilage :

RTS - Return from Subroutine (Retour de sous-programme)

Dépile l'adresse de retour de la pile et y ajoute 1 pour continuer l'exécution après l'instruction JSR correspondante.

Opération : PULL PC, PC ← PC + 1

Drapeaux affectes : aucun

Opcode Taille Cycles
$60 1 octet 6

Détail du dépilage :

Exemple :

  1.     JSR MaRoutine     ; appel
  2.     ; ... continue ici apres RTS ...
  3.  
  4.   MaRoutine:
  5.     ; ... code ...
  6.     RTS               ; retour a l'appelant

Astuce : JMP indirect simule par PUSH + RTS :

  1.     ; Pour simuler un JMP indirect via un pointeur en page zero :
  2.     LDA $81           ; poids fort de l'adresse cible
  3.     PHA
  4.     LDA $80           ; poids faible de l'adresse cible
  5.     PHA
  6.     RTS               ; "retourner" a l'adresse ($80)/$81
  7.     ; Note : empiler (adresse - 1) car RTS ajoute 1

RTI - Return from Interrupt (Retour d'interruption)

Dépile le registre d'état puis l'adresse de retour depuis la pile. Contrairement a RTS, RTI ne modifie PAS l'adresse dépilée (pas de +1), car lors d'une interruption, le PC exact est empile.

Opération : PULL P, PULL PC

Drapeaux affectes : tous (restaures depuis la pile)

Opcode Taille Cycles
$40 1 octet 6

Détail du dépilage :

Exemple :

  1.     ; Gestionnaire d'interruption IRQ
  2.   GestionnaireIRQ:
  3.     PHA               ; sauvegarder A
  4.     TXA
  5.     PHA               ; sauvegarder X
  6.     TYA
  7.     PHA               ; sauvegarder Y
  8.  
  9.     ; ... traitement de l'interruption ...
  10.  
  11.     PLA
  12.     TAY               ; restaurer Y
  13.     PLA
  14.     TAX               ; restaurer X
  15.     PLA               ; restaurer A
  16.     RTI               ; retourner de l'interruption

Remarques :

BRK - Break (Interruption logicielle)

Génère une interruption logicielle. Empile PC+2 et P sur la pile, positionne le drapeau I, et saute au vecteur d'interruption IRQ/BRK ($FFFE-$FFFF).

Opération :

PC := PC + 2 (pointe après BRK + octet de signature)
PUSH PCH
PUSH PCL
PUSH P (avec B = 1)
I := 1
PC := [$FFFE]:[$FFFF]

Drapeaux affectes : I est positionne. B est positionne dans la copie empilée de P (mais pas dans P lui-même).

Opcode Taille Cycles
Opcode : $00 1 octet* 7

* Note : BRK est formellement une instruction de 1 octet, mais le PC empile pointe 2 octets APRES le BRK. L'octet suivant le BRK est considéré comme un "octet de signature" (padding byte) étant sauté. Cet octet peut être utilisé par le gestionnaire d'interruption pour identifier la raison du BRK.

Exemples :

  1.     ; Interruption logicielle simple
  2.     BRK               ; declencher une interruption logicielle
  3.     .BYTE $01         ; signature (optionnel, utilise par le handler)
  4.  
  5.     ; Dans le gestionnaire d'interruption, distinguer BRK de IRQ :
  6.   GestionnaireIRQ:
  7.     ; ... sauvegarder les registres ...
  8.     PLA               ; recuperer P de la pile
  9.     PHA               ; le remettre
  10.     AND #$10          ; tester le bit B (Break)
  11.     BNE EstBRK        ; si B=1, c'est un BRK
  12.     ; Sinon, c'est une IRQ materielle
  13.     ; ...
  14.   EstBRK:
  15.     ; Traiter le BRK
  16.     ; ...

Remarques :

Instructions de pile

Ces instructions empilent ou dépilent des valeurs sur la pile située en page 1 ($0100-$01FF).

PHA - Push Accumulator (Empiler A)

Empile le contenu de l'accumulateur sur la pile.

Opération : [$0100+SP] ← A, SP ← SP - 1

Drapeaux affectes : aucun

Opcode Taille Cycles
$48 1 octet 3

Exemple :

  1. PHA               ; sauvegarder A sur la pile

PLA - Pull Accumulator (Depiler A)

Dépile une valeur de la pile dans l'accumulateur.

Opération : SP ← SP + 1, A ← [$0100+SP]

Drapeaux affectes : N, Z

Opcode Taille Cycles
$68 1 octet 4

Exemple :

  1. PLA               ; restaurer A depuis la pile

Remarque : PLA affecte N et Z, contrairement a PHA.

PHP - Push Processor Status (Empiler P)

Empile le registre d'état du processeur sur la pile.

Opération : [$0100+SP] ← P (avec B=1), SP ← SP - 1

Drapeaux affectes : aucun

Opcode Taille Cycles
$08 1 octet 3

Remarque : PHP empile TOUJOURS P avec le drapeau B positionne a 1 et le bit 5 (inutilise) a 1.

PLP - Pull Processor Status (Dépiler P)

Dépile une valeur de la pile dans le registre d'état.

Opération : SP ← SP + 1, P ← [$0100+SP]

Drapeaux affectes : tous (restaures depuis la valeur dépilée)

Opcode Taille Cycles
$28 1 octet 4

Exemple :

  1. ; Sauvegarder et restaurer les drapeaux
  2. PHP               ; sauvegarder P
  3. ; ... code qui modifie les drapeaux ...
  4. PLP               ; restaurer P (tous les drapeaux)

Remarques :

Exemple : sauvegarder X et Y via la pile :

  1. ; Le 6502 n'a pas de PHX/PHY (ajoutes sur le 65C02)
  2. ; Pour sauvegarder X :
  3. TXA               ; A := X
  4. PHA               ; empiler A (qui contient X)
  5. ; Pour restaurer X :
  6. PLA               ; depiler dans A
  7. TAX               ; X := A
  8. ; Idem pour Y avec TYA/PHA et PLA/TAY

Instructions de contrôle des drapeaux

Ces instructions modifient directement les drapeaux du registre d'état P. Elles sont en mode implicite (1 octet, 2 cycles).

CLC - Clear Carry Flag (Effacer la retenue)

Opération : C ← 0

Opcode Taille Cycles
$18 1 octet 2

Utilisation : OBLIGATOIRE avant ADC pour éviter une retenue parasite dans l'addition

Exemple :

  1. CLC
  2. LDA #$30
  3. ADC #$10          ; A = $40 (et non $41 si C etait 1)

SEC - Set Carry Flag (Positionner la retenue)

Opération : C ← 1

Opcode Taille Cycles
$38 1 octet 2

Utilisation : OBLIGATOIRE avant SBC pour éviter un emprunt parasite dans la soustraction.

Exemple :

  1. SEC
  2. LDA #$50
  3. SBC #$20          ; A = $30 (et non $2F si C etait 0)

CLD - Clear Decimal Mode (Desactiver le mode decimal)

Opération : D ← 0

Opcode Taille Cycles
$D8 1 octet 2

Utilisation : revenir en mode binaire après des calculs BCD, ou en début de programme pour s'assurer du mode binaire.

Exemple :

  1. CLD               ; s'assurer que le mode binaire est actif
  2. ; ... code arithmetique normal ...

Remarque : le 6502 NMOS ne définit pas l'état du drapeau D après un RESET ou une IRQ. Il est recommande de faire CLD au début de tout programme et de tout gestionnaire d'interruption.

SED - Set Decimal Mode (Activer le mode décimal)

Opération : D ← 1

Opcode Taille Cycles
$F8 1 octet 2

Utilisation : activer le mode BCD pour ADC et SBC

Exemple :

  1. SED               ; activer le mode BCD
  2. CLC
  3. LDA #$15
  4. ADC #$27          ; A = $42 (15 + 27 = 42 en decimal)
  5. CLD               ; revenir en mode binaire

Remarque : en mode BCD, seuls ADC et SBC sont affectes. Les autres instructions (INC, DEC, etc.) continuent a fonctionner en binaire.

CLI - Clear Interrupt Disable (Autoriser les interruptions)

Opération : I ← 0

Opcode Taille Cycles
$58 1 octet 2

Utilisation : re-autoriser les interruptions IRQ après les avoir désactivées.

Exemple :

  1. CLI               ; autoriser les interruptions IRQ

Remarque : les interruptions NMI ne sont PAS affectées par le drapeau I. Elles sont toujours actives.

SEI - Set Interrupt Disable (Masquer les interruptions)

Opération : I ← 1

Opcode Taille Cycles
$78 1 octet 2

Utilisation : désactiver les interruptions IRQ pendant une section critique du code.

Exemple :

  1. SEI               ; desactiver les interruptions IRQ
  2. ; ... section critique ...
  3. ; ... modifier des donnees partagees avec l'IRQ ...
  4. CLI               ; re-autoriser les interruptions

CLV - Clear Overflow Flag (Effacer le débordement)

Opération : V ← 0

Opcode Taille Cycles
$B8 1 octet 2

Utilisation : effacer le drapeau de débordement. Rarement utilise en pratique.

Remarques :

Résumé des instructions de contrôle des drapeaux :

Instruction Opcode Opération Utilisation principale
CLC $18 C ← 0 Avant ADC
SEC $38 C ← 1 Avant SBC
CLD $D8 D ← 0 Mode binaire (début programme)
SED $F8 D ← 1 Mode BCD
CLI $58 I ← 0 Autoriser les IRQ
SEI $78 I ← 1 Masquer les IRQ
CLV $B8 V ← 0 Effacer le débordement

Instruction NOP

NOP - No Operation (Pas d'opération)

Ne fait rien. Le processeur consomme du temps et de l'espace sans modifier l'état du processeur (aucun registre ni drapeau modifié).

Opération : aucune

Drapeaux affectes : aucun

Opcode Taille Cycles
$EA 1 octet 2

Utilisations :

Exemples :

  1. ; Delai precis de 10 cycles
  2. NOP               ; 2 cycles
  3. NOP               ; 2 cycles
  4. NOP               ; 2 cycles
  5. NOP               ; 2 cycles
  6. NOP               ; 2 cycles (total : 10 cycles)
  7.  
  8. ; Patcher du code : remplacer un JSR par des NOP
  9. ; Avant : JSR $C000 (3 octets: $20 $00 $C0)
  10. ; Apres : NOP NOP NOP (3 octets: $EA $EA $EA)

Résumé et tableau récapitulatif

Le 6502 possède 56 instructions officielles reparties en 11 catégories. Voici le tableau récapitulatif complet :

Instructions de transfert de données (12 instructions)

Mnémonique Description Drapeaux
LDA Charger A depuis la mémoire N, Z
LDX Charger X depuis la mémoire N, Z
LDY Charger Y depuis la mémoire N, Z
STA Entreposer A en mémoire -
STX Entreposer X en mémoire -
STY Entreposer Y en mémoire -
TAX Transférer A vers X N, Z
TAY Transférer A vers Y N, Z
TXA Transférer X vers A N, Z
TYA Transférer Y vers A N, Z
TSX Transférer SP vers X N, Z
TXS Transférer X vers SP -

Instructions arithmétiques (8 instructions)

Mnémonique Description Drapeaux
ADC Addition avec retenue N, V, Z, C
SBC Soustraction avec retenue N, V, Z, C
INC Incrémenter la mémoire N, Z
INX Incrémenter X N, Z
INY Incrémenter Y N, Z
DEC Décrémenter la mémoire N, Z
DEX Décrémenter X N, Z
DEY Décrémenter Y N, Z

Instructions logiques (3 instructions)

Mnémonique Description Drapeaux
AND ET logique avec A N, Z
ORA OU logique avec A N, Z
EOR OU exclusif avec A N, Z

Instructions de décalage/rotation (4 instructions)

Mnémonique Description Drapeaux
ASL Décalage a gauche N, Z, C
LSR Décalage logique a droite N, Z, C
ROL Rotation a gauche via C N, Z, C
ROR Rotation a droite via C N, Z, C

Instructions de comparaison (4 instructions)

Mnémonique Description Drapeaux
CMP Comparer A avec la mémoire N, Z, C
CPX Comparer X avec la mémoire N, Z, C
CPY Comparer Y avec la mémoire N, Z, C
BIT Tester des bits en mémoire N, V, Z

Instructions de branchement (8 instructions)

Mnémonique Description Condition
BCC Brancher si C = 0 C = 0
BCS Brancher si C = 1 C = 1
BEQ Brancher si Z = 1 (égal) Z = 1
BNE Brancher si Z = 0 (différent) Z = 0
BMI Brancher si N = 1 (négatif) N = 1
BPL Brancher si N = 0 (positif) N = 0
BVC Brancher si V = 0 V = 0
BVS Brancher si V = 1 V = 1

Instructions de saut et d'appel (5 instructions)

Mnémonique Description Drapeaux
JMP Saut inconditionnel -
JSR Appel de sous-programme -
RTS Retour de sous-programme -
RTI Retour d'interruption tous
BRK Interruption logicielle I

Instructions de pile (4 instructions)

Mnémonique Description Drapeaux
PHA Empiler A -
PLA Dépiler A N, Z
PHP Empiler P -
PLP Depiler P tous

Instructions de contrôle des drapeaux (7 instructions)

Mnémonique Description Opération
CLC Effacer la retenue C ← 0
SEC Positionner la retenue C ← 1
CLD Désactiver le mode décimal D ← 0
SED Activer le mode décimal D ← 1
CLI Autoriser les interruptions I ← 0
SEI Masquer les interruptions I ← 1
CLV Effacer le débordement V ← 0

Instruction NOP (1 instruction)

Mnémonique Description Drapeaux
NOP Pas d'opération -

Total : 56 instructions, 151 opcodes valides (sur 256 possibles)

Les 105 opcodes restants sont non documentes ("illegal opcodes"). Certains produisent des effets utiles exploites par les programmeurs.

Comparaison avec d'autres processeurs :

Processeur Instructions Opcodes valides Registres
MOS 6502 56 151 3 (A,X,Y)
Zilog Z80 158 694 (avec CB/DD) 14
Intel 8080 78 244 7
Motorola 6800 72 197 2 (A,B)
Motorola 6809 86 ~210 6
Motorola 68000 56+ ~140 base 16 (D0-D7,A0-A7)
Intel 8086 ~100 ~300 8 GPR

Le 6502, avec ses 56 instructions, est l'un des processeurs les plus simples de sa génération. Malgré ce minimalisme, la richesse de ses modes d'adressage (13 modes) et l'utilisation créative de la page zéro permettent d'écrire du code compact et performant.



Dernière mise à jour : Lundi, le 23 mars 2026