CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Aide CHIP8

stuart4
stuart4
Niveau 5
28 décembre 2021 à 12:38:15

Bonjour je me suis lancé dans un projet de concevoir un émulateur l'interpréteur CHIP8 en C.

Grâce au nombreuse ressource disponible sur internet je comprends plus ou moins comment ce dernier fonctionne cepandant j'ai du mal a identifier la fonction des différents registers.

Tout d'abord quelle est la fonction précise d'un register (stocker de la data et des adresse ?) Et ensuite j'ai du mal a comprendre la relation entre register, index register, program counter et stack pointer.

Quelqu'un pourrai-t-il m'expliquer?

Je tiens vraiment a continuer ce projet car je le trouve très enrichissant j'ai déjà beaucoup appris (comment fonctionne un buffer, mask, comment fonctionne les instructions d'une machine) et j'adore ca.

Pseudo supprimé
Pseudo supprimé 28 décembre 2021 à 13:37:47

Les registres c'est juste de la mémoire facile d'accès qui servent à stocker des résultats intermédiaires que tu veux pas stocker sur la durée.

Imaginons un hypothétique jeu pokemon sur CHIP8, dans la mémoire du CHIP8 t'aurais toutes les informations du type : ton équipe, les coordonnées de ton personnage, la carte sur laquelle tu te trouves, ton nombre de badges

Maintenant imaginons que t'aies un item qui permette de multiplier par 2 le niveau de ton pokemon, CHIP8 permet pas de faire de multiplication et encore moins de multiplication directement dans la mémoire.

Du coup pour ça va falloir implémenter à la main

LD I addr ; on stocke l'adresse où le niveau du pokémon est stockée dans le registre I qui sert à stocker des adresses mémoire
LD V0 [I] ; on lit le niveau du pokemon dans le registre V0
ADD V0 V0 ; on multiplie par 2 V0 et on stocke le résultat dans V0
LD [I] V0 ; on écrit le résultat là où était stocké le niveau du pokémon

Finalement on a récupéré le niveau du pokémon, on l'a ajouté à lui-même dans le registre V0 puis on a écrit le résultat là où était l'ancien niveau, donc on a bien fait ce qu'on voulait.

Grossomodo dès que tu vas devoir faire des opérations sur tes données tu vas les faire dans un ou des registres et à la fin seulement tu écriras le résultat final dans la mémoire.

Pseudo supprimé
Pseudo supprimé 28 décembre 2021 à 13:51:18

Ensuite pour le reste de ta question, l'idée schématique de CHIP8 c'est ça :

T'as un clavier
T'as un écran
T'as un timer
T'as de la RAM (la mémoire)
T'as différentes registres (V0, ..., VF pour stocker des bytes, I pour stocker des adresses, et des registres décrémentés automatiquement à une certaine fréquence par le timer)
T'as une stack de 16 adresses
Un CPU qui orchestre le tout

Lorsque tu "lances" le CHIP8 le CPU va commencer par lire deux bytes en 0x200, ces deux bytes vont correspondre à une instruction élémentaire. Par exemple 0x00e0 (CLS) c'est une instruction qui va remettre à zéro l'écran. Donc le CPU va lire ces deux premiers bytes, exécuter l'instruction correspondante puis passer aux deux prochains bytes etc.

Il faut t'imaginer une sorte de curseur qui pointe vers l'instruction en train d'être traitée, et à chaque fois ce curseur est décalé de deux bytes après avoir lu l'instruction.

Ce curseur on peut le représenter par l'adresse de l'instruction et on l'appelle program counter (PC). Autrement dit, au début PC = 0x200 puis après avoir lu la première instruction PC = 0x202 etc.

Il y a certaines instructions qui modifient directement PC, par exemple JP addr permet de définir la valeur de PC explicitement.

Le programme JP 0x200 consiste donc en une boucle infinie puisque le CPU va lire l'instruction avec PC=0x200 puis va incrémenter PC=0x202 puis va exécuter l'instruction PC=0x200, etc. en boucle.

La stack c'est une forme de mémoire comme les registres mais avec plus de "structure", en l'occurrence une structure de pile. Tu vas pouvoir stocker une information en haut de la pile ou récupérer l'information en haut de la pile dans ton CPU.

L'intérêt fondamental de la stack dans le CHIP8 c'est de servir de call stack, c'est-à-dire de mémoriser les valeurs de PC pour pouvoir continuer l'exécution où on l'a interrompue précédemment si nécessaire.

Tout ça c'est lié au concept de procédure. Une procédure c'est un petit bout de code vers lequel on va sauter pour effectuer une certaine opération. Le problème c'est qu'on a besoin de revenir où on était avant d'avoir fait l'appel à la procédure une fois qu'elle a fini de s'exécuter, pour ça on doit stocker la valeur de PC avant d'effectuer le saut. On va donc pousser cette valeur sur la stack et quand la procédure aura terminé on récupérera la valeur en haut de la stack et on y sautera.

L'idée d'avoir une stack et pas juste un registre pour ça c'est que ça permet d'avoir des procédures imbriquées. Tu peux imaginer appeler PROC2 depuis PROC1.

Le rôle du stack pointer dans tout ça c'est simplement de désigner le haut de la pile. En incrémentant le stack pointer on "monte" dans la pile et en décrémentant on "descend" dans la pile.

Message édité le 28 décembre 2021 à 13:54:28 par Pseudo supprimé
stuart4
stuart4
Niveau 5
28 décembre 2021 à 13:54:20

Et quel est l'intérêt du program counter de l'index register ?

stuart4
stuart4
Niveau 5
28 décembre 2021 à 13:55:00

J'avais pas vu ton 2ème message merci.

Pseudo supprimé
Pseudo supprimé 28 décembre 2021 à 13:58:46

L'index register noté I c'est juste un registre qui permet de stocker une adresse mémoire.

Les registres Vx contiennent un byte = 8bits de données là où I contient au moins 12 bits de données pour pouvoir stocker n'importe quelle adresse mémoire directement. (En général on implémente I comme un entier 16-bits puisque c'est le multiple de 8 supérieur et ça permet de stocker ça dans un nombre rond de bytes.)

stuart4
stuart4
Niveau 5
28 décembre 2021 à 14:02:32

En fait le stack fonctionne de la même manière que en C quand main() call une fonction et puis que cette fonction call une autre fonction et si cette dernière n'en call pas d'autre on revient a la main() fonction

stuart4
stuart4
Niveau 5
28 décembre 2021 à 14:03:56

Par contre je ne comprends toujours pas la raison pour laquelle I fait 12 bits?

Pseudo supprimé
Pseudo supprimé 28 décembre 2021 à 14:07:09

Le 28 décembre 2021 à 14:02:32 :
En fait le stack fonctionne de la même manière que en C quand main() call une fonction et puis que cette fonction call une autre fonction et si cette dernière n'en call pas d'autre on revient a la main() fonction

Oui c'est pareil, c'est basé sur le même mécanisme de CALL/RETURN

Le 28 décembre 2021 à 14:03:56 :
Par contre je ne comprends toujours pas la raison pour laquelle I fait 12 bits?

Parce que la mémoire du CHIP8 est une mémoire 12-bits. Autrement dit y a 2¹² = 4096 bytes stockés dans la mémoire.

Pourquoi 12 et pas 16 par exemple ? L'idée c'est que ça permet que tous les opcodes soient codés sur 2 bytes ce qui rend l'implémentation particulièrement facile.

Prends les opcodes 0nnn et 1nnn où nnn représente une adresse, 0 et 1 sont codés sur 4 bits et nnn est codé sur 12 bits de sorte qu'on obtienne des opcode sur 16 bits.

stuart4
stuart4
Niveau 5
28 décembre 2021 à 14:13:18

Et tout est dans cette mémoire? Ou les registers sont dans le cpu et le stack est dans le stack ?

Pseudo supprimé
Pseudo supprimé 28 décembre 2021 à 14:15:22

T'as un clavier
T'as un écran
T'as un timer
T'as de la RAM (la mémoire)
T'as différentes registres (V0, ..., VF pour stocker des bytes, I pour stocker des adresses, et des registres décrémentés automatiquement à une certaine fréquence par le timer)
T'as une stack de 16 adresses
Un CPU qui orchestre le tout

Comme j'ai dit ici, la mémoire est à part.

Dans la mémoire concrètement t'as : les sprites des chiffres de 0 à F entre 0x0 et 0x200, en 0x200 t'as le début du programme à faire tourner et le reste de la mémoire est libre pour que le programme stocke des choses dedans

Tout le reste c'est hors de la mémoire

stuart4
stuart4
Niveau 5
28 décembre 2021 à 16:23:55

J'ai presque tout compris si ce n'est l'intérêt de I ?

stuart4
stuart4
Niveau 5
28 décembre 2021 à 17:56:50

Je ne comprends pas l'intérêt de l'index register

RegleGraduee
RegleGraduee
Niveau 71
28 décembre 2021 à 20:13:24

Le 28 décembre 2021 à 16:23:55 :
J'ai presque tout compris si ce n'est l'intérêt de I ?

C'est juste un registre comme un autre qui est "réservé" pour stocker une adresse mémoire

Sous forums
  • Aide à l'achat Mac
  • Internet
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment