1) Les fondamentaux du CPU :
Pour commencer un petit schéma simplifié :
Code : Tout sélectionner
CPU
---------------------------
! ! ! !
Registres Pile Status PC
Qu'est ce que les registres et à quoi ça sert ?
Code : Tout sélectionner
Les registres servent au CPU à faire toutes les opérations aussi bien arithmétique, logique, que de transfert (lecture et écriture).
Sur le TMS7020 les registres sont aux nombres de 128 :) :) parmi ces registres il y a les 2 accumulateurs respectivement A et B.
les accumulateurs servent en général pour tout ce qui est calcul, et n'ont pas la vocation à être conservés, c'est à dire que par "convention" une fois l'opération effectuée on stocke le résultat en mémoire ou dans un registre autre que A ou B, ce sont des registres temporaires du fait même que la ROM les utilise abondamment il faut donc ne pas conserver les résultats de calcul dans les accumulateurs pour ne pas voir ces résultats être altérés.
Code : Tout sélectionner
Les autres registres sont définis par Texas Instruments de R2 à R127, dans les sources assembleurs pour TMS7020 ces registres seront donc nommés Rxxx, par exemple si on veut additionner le registre 10 avec le registre 12 cela donnera ceci :
ADD R10,R12.
La particularité du TMS7020 c'est que l'on peut faire toutes les opérations avec n'importe quel registre (calcul, comparaison, ecriture, lecture, transfert, ...) et pas seulement avec les accumulateurs.
Mais parce-qu'il y a toujours un mais, Exelvision utilise certains des registres pour son moniteur en ROM, donc il faut éviter d'utiliser les registres R2 à R32, pour être sur que l'ordinateur ne sera pas planté, ou que votre programme aura un comportement non attendu.
La pile ?
Code : Tout sélectionner
la pile, non pas celle à fusion mais celle du microprocesseur, c'est un peu comme une pile de dossier sur un bureau d'une administration, le premier dossier est posé sur le bureau, puis vient un deuxième dossier que l'on pose par dessus le précédent et ainsi de suite, jusqu'à ce qu'il n'y ait plus de place.
Evidemment dans notre microprocesseur il n'y a pas de bureau et de dossier mais des octets qui seront donc empilés dans la pile, et lorsque l'on a besoin de prendre le dernier élément empilé dans la pile on dépile l'octet.
Mais on ne peut pas prendre l'octet qui est au milieu de la pile ou tout en bas, uniquement le dernier empilé*.
Code : Tout sélectionner
Bon c'est bien beau tout ça mais je vois bien que vous ne voyez pas trop à quoi ça peut servir ???
Tout simplement si l'on veut par exemple faire plusieurs opérations avec des sous-totaux, un peu comme dans notre administration pour calculer votre impôt par exemple, on va additionner tous vos salaires et faire un premier sous-total ensuite on va additionner tous vos revenus de capitaux et faire un deuxième sous-total, idem avec d'autres types de revenus et à la fin on reprend nos sous-totaux pour en faire un grand total, etc, etc...
En assembleur l'usage de la pile se fait par 2 instructions : PUSH (empiler) et POP (dépiler).
Code : Tout sélectionner
Un petit exemple :
LDA #$01
LDB #$02
ADD A,B
PUSH B
>le résultat de l'addition (B) est empilé dans la pile ($03)
LDA $c600
PUSH A
>la valeur lue en $C600 est empilée dans la pile ($FF)
LDB $C601
POP A
>on dépile la dernière valeur stockée dans la pile dans A ($FF)
ADD A,B
POP A
>on dépile la dernière valeur stockée dans la pile dans A ($03)
Il y a beaucoup d'autres usages de la pile évidemment.
Code : Tout sélectionner
Comment fait le microprocesseur pour s'y retrouver, il utilise un index d'adresse que l'on appelle SP,
cet index est initialisé par l'instruction LDSP, pour ça il faut au préalable initialiser l’accumulateur B
avec l'index correspondant à l'adresse qui servira de début de la pile en mémoire, en sachant que la pile
peut aller jusqu’à $7F.
Exemple si l'on veut réserver la zone $70 à $7F pour la pile on devra écrire ce programme:
LDB #$70
LDSP
A chaque utilisation de la pile par PUSH ou POP l'index SP est mis à jour, exemple si SP est à $64 après PUSH SP aura comme valeur $65 (+1), si après on utilise POP SP aura comme valeur $64 (-1).
Mais, parce-qu'il y a toujours un mais, la pile est aussi située dans la zone des registres Rxxx, ce qui fait que l'on doit bien faire attention à initialiser la pile pour limiter l'usage de la pile dans cette zone,
surtout si vous comptez utiliser beaucoup de registres Rxxx dans vos programmes.
*On peut évidemment trouver une astuce pour prendre un octet qui serait n'importe ou dans la pile mais cela dépasse notre introduction ;)
Status
Code : Tout sélectionner
On aborde avec le Status un point essentiel dans le fonctionnement des programmes en assembleur.
Le Status est un registre unique qui nous indique après chaque instruction exécutée l'état du CPU concernant Carry, Negative, Zero et interruptions. Ces indicateurs sont extrêmement utiles dans la programmation en assembleur, et bien pratiques car sans eux nous aurions beaucoup de mal à écrire certains programmes.
Il sont représentés par le registre ST et sur un octet reparti comme ceci:
C N Z I 0 0 0 0
Donc ces indicateurs kezako et à quoi peuvent-ils servir ?
Code : Tout sélectionner
Carry nous indique si une opération à provoqué une retenue, par exemple si on additionne $F0 et $10 le CPU positionnera Carry à 1, puisque $F0 et $10 donne un résultat supérieur à $FF, par contre si on additionne $F0 et $0F le CPU positionnera Carry à 0, puisque l'on ne dépassera par $FF.
Carry est aussi pris en compte dans les opérations arithmétiques avec retenues, par exemple avec ADC
ADC R63,R64 sera traité comme ceci : R63 + R64 + Carry.
Negative nous indique le bit le plus significatif après l’exécution de l'instruction, par exemple après STA $C000 si A contient $F0 le CPU positionnera Negative à 1, par contre si A contient $0F le CPU positionnera Negative à 0.
Zero nous indique si le résultat d'une opération est égale à zéro, très pratique pour les comparaisons. Par exemple si l'on compare A contenant la valeur $20 avec B contenant la valeur $20 le CPU positionnera Zero à 1, par contre si on compare A ($20) avec B contenant $10 le CPU positionnera Zero à 0.
Interruption nous indique si les interruptions sont actives ou non.
Si I=1 les interruptions sont actives si I=0 les interruptions sont inactives.
Je ne rentre pas dans les cas particuliers qui sont expliqués avec chaque instruction du CPU (voir le Datasheet).
PC
Code : Tout sélectionner
PROGRAM COUNTER de son nom complet est en fait l'adresse de la prochaine instruction à exécuter.
Lorsque le CPU démarre, il va lire les 2 octets présents en $FFFE et $FFFF les place dans PC et exécute la premier instruction à cette adresse, puis écrit l'adresse de la prochaine instruction à exécuter dans PC, etc, etc...
Par exemple si dans $FFFE et $FFFF on avait $20 $00 et que l'on ait ce programme en $2000 :
adresse code machine mnemonique TMS7020
2000 72 00 28 mov %00,R40
2003 72 02 27 mov %02,R39
2006 22 14 mov %20,a
2008 8B C1 00 sta @$C100
200B 22 15 mov %21,a
200D 8B C1 01 sta @$C101
2010 0A RETS
Donc PC démarre en $2000, exécute l'instruction mov $00,R40 et met à jour PC en fonction de l'instruction
soit $2003 puis exécute mov %02,R39 et met à jour PC en $2006, puis exécute l'instruction suivante et
met à jour PC en $2008, etc, etc .
Comme vous l'aurez remarqué chaque instruction n'a pas la même taille en code machine, par exemple
MOV $00,R40 occupe 3 octets, par contre RETS occupe 1 seul octet.
2) Les Ports Entrées/Sorties :
Code : Tout sélectionner
Non pas Marseille ou La Rochelle, mais les ports de l'EXEL100.
Les Entrées/Sorties ce sont tous les périphériques internes ou externes à l'ordinateur.
Aussi bien les coprocesseurs comme le VDP, SYNTHESE VOCALE, TMS7041 (I/O) que les périphériques externes comme l'Exelmodem, l'Exeldrums, Triplex, etc, etc ...
Et même les interruptions du CPU passent par les ports.
Donc pour accéder à tous ces périphériques le CPU utilise une zone que l'on appelle PORT, cette zone est située en RAM entre $100 et $1FF, Texas Instruments utilise une notation spécifique pour accéder à ces ports: P0 - P255 et plusieurs instructions du TMS7020 sont spécialisées pour les opérations avec ces ports, comme par exemple les instructions logique ANDP, ORP, XORP ou l'instruction de lecture/ecriture MOVP. Pour les accès au VDP, le TMS7020 possède des instructions spécifiques LVDP et WVDP.
Exemple d'adresses de ports sur l'EXEL100 :
-P0 registre de controle des Interruption du TMS (CPU)
-P2 réglage du Timer du TMS (CPU)
-P3 réglage et déclenchement du Timer du TMS (CPU)
-P36 est le port de lecture en mémoire vidéo
Pour plus de détails sur chaque ports reportez vous au bouquin "Programmer en assembleur sur Exelvision".
3) La mémoire
Tout d'abord il faut savoir que l'EXL100 possède seulement 2Ko de RAM propre au CPU et 32Ko de RAM
dédié au VDP pour l'affichage.
Mais comment est ce possible que le Basic de l'EXL100 nous retourne plus de 20Ko de RAM disponible pour
les programmes basics ???
Mais c'est par ce que chez Exelvision il y avait des magiciens, non évidemment mais c'est tout simplement
grâce à une astuce des développeurs de l'Exelbasic, qui se sont servi de la VRAM comme d'un support de
stockage pour le programme basic en cours.
Le seul inconvénient c'est que cette espace RAM ne peut servir à exécuter un programme
en langage machine, car le CPU ne peut y accéder directement, il doit passer absolument par le VDP.
Vous comprenez mieux pourquoi l'Exelbasic est si lent
Evidemment sous basic vous ne pourrais utiliser un peu moins de 2Ko pour loger vos routines assembleur,
à moins de posséder une Exelmémoire et la vous aurez une profusion de mémoire supplémentaire de 16Ko
pour vos programme assembleur.
Un petit schéma pour illustrer l'organisation de la RAM CPU et VRAM vidéo:
Code : Tout sélectionner
CPU
!
-------------------
! !
RAM VDP
2Ko !---- VRAM 32Ko
impérativement passer par le VDP, ce qui ralenti au passage le traitement de l'information.
La table mémoire (pour un EXL100):
Code : Tout sélectionner
$F000-$FFFF : ROM (moniteur)
$D000-$EFFF : CROS (gestion de l'EXELMEMOIRE)
$C800-$CFFF : inutilisé
$C000-$C7FF : RAM CPU 2 Ko
$8000-$BFFF : RAM (EXELMEMOIRE) 16 Ko
$0200-$7FFF : Cartouche (ROM) 32 Ko
$0100-$01FF : zone des Ports I/O
$0080-$00FF : inutilisé
$0000-$007F : Registres et Piles
Particularité de la mémoire de l'EXL100 que l'on peut perdre pendant le déroulement des programmes basics
Oui c'est pas une blague, et encore une fois ce n'est pas dû à un quelconque sort de magie de merlin, mais encore une fois à cause de la gestion de la VRAM utilisé par le Basic pour y stocker le programme en cours.
Vous pouvez faire l'expérience vous aussi en utilisant DCexel et la cartouche Exelbasic+ (plus pratique pour connaitre la mémoire disponible).
Donc vous démarrez l'émulateur vous insérez Exelbasic+ en cartouche vous sélectionnez bien EXEL100 sans lecteur.
tapez ces commandes dans l'émulateur ou la machine réel :
PRINT FRE(0)
-> 26646
CALL HRON("Y",1,20)
-> un beau cadre jaune (ca correspond à l'ecran bitmap)
PRINT FRE(0)
-> 3886
et vous n'avez saisi aucun programme pourtant la mémoire disponible pour le Basic à perdu presque 23ko !!!
on continue l'expérience pour bien vous faire comprendre l'importance de la gestion de le RAM sous Basic.
CALL HROFF
-> le cadre jaune disparait (on revient à l'ecran texte)
PRINT FRE(0)
-> 26646
On à retrouvé notre mémoire
Donc imaginez que vous saisissiez un programme très long qui occuperais une dizaine de Ko voir plus et que
dans ce programme vous voulez utiliser le mode graphique, à la fin de votre saisie vous vérifiez qu'il vous
reste assez de place pour les variables, avec 12Ko de programmes sur les 26 Ko il y a de la marge et pourtant
après RUN le programme plante dès qu'il tente d'executer la commande CALL HRON, tout simplement parcequ'il n'a
pas assez de mémoire pour le programme et l'écran Bitmap, puisque le basic utilise la VRAM pour stocker son programme
et que l'on à vu que la commande CALL HRON qui initialise le mode BITMAP prend une vingtaine de Ko de la VRAM,
il y a donc conflit et le basic retourne une erreur.
Il y aurais de quoi écrire plusieurs pages sur la gestion de la mémoire avec l'EXL100, mais sans rentrer dans
plus de détails l'EXELMEMOIRE n'est pas à considérer comme de la RAM utilisable par votre programme basic, mais plus
comme une RAM pour stocker les programme assembleurs ou les données, à savoir que l'EXELMEMOIRE à une pile qui
lui permet de sauvegarder pendant au moins 2 ans les données écrites dessus.
LA SUITE
J'éditerais le post au fur et à mesure, donc à visiter régulièrement
PS: Je ne suis pas très doué pour l'orthographe, si un modérateur à le courage de corriger