documentation rédigée par whyp
Il existe plusieurs types de mémoires internes dans la graph100, dont voici les noms et caractéristiques techniques :
Type | Nom | Temps d’accès | Taille | Opérations |
---|---|---|---|---|
Sram | Nec PD442000GU-B85X-9JH | 85ns max | 256Ko | Lecture / écriture |
Flash | Fujitsu MBM29LV800BA-90 | 90ns max | 8Mbit soit 16x64Ko soit 1Mo | Lecture / écriture |
Rom Graph100 | Nec PD23C32000L | 140ns max | 32Mbit soit 4Mo | Lecture |
Rom Graph100+ | Oki MR53V3202K-24 | 120ns max | 32Mbit soit 4Mo | Lecture |
Par la suite, nous ne ferons pas de différence entre la rom de la graph100 et celle de la graph100+ car elles s’utilisent de la même manière.
C’est la mémoire vive de la graph100. Elle se situe entre les adresses 0000h:0000h et 4000h:0000h. Elle ne mesure que 256 Ko, alors que le plupart des ordinateurs équivalents possédaient 640 Ko. Ceci va grandement nous pénaliser dans omme dans un ordinateur en mode réel. Car ici, vous l’aurez compris, pas question de mode protégé.
Adresse | Contenu |
---|---|
0000h:0000h - 0000h:03FFh | Table des vecteurs d’interruptions |
0000h:0400h - 0000h:04FFh | Variables du bios |
0000h:0500h - 1000h:A1FFh | Zone dos, pour charger les programmes, les variables, l’environnement... |
1000h:A200h - 1000h:C1FFh | Buffer mémoire vidéo |
1000h:C200h - 3000h:FFFFh | Programmes basics, matrices, listes, tout les éléments de calculs de la graph100 |
La rom de la graph100 mesure 4 Mo. Elle contient les programmes de calcul de la graph100, une sauvegarde de la zone système et du lecteur A :, le menu constructeur, et les langues de la calculette. Voici la manière dont elle est organisée par segments:
Segment | Contenu |
---|---|
0000h - 0FFFh | Zone système de base |
1000h - 2FFFh | Menu constructeur |
3000h - 3FFFh | Sauvegarde Lecteur A: |
4000h - 5FFFh | Langues pour le système |
6000h - 6FFFh | Vide |
7000h - 7FFFh | ? - Bout de programmes |
8000h - 3FFFFh | Lecteurs B: à K: |
Mais ces adresses sont les adresses physiques internes de la rom, et en aucun cas celles auxquelles on trouve ces données en mémoire. Pour y accéder depuis la mémoire, il faut « mapper » une zone de ce disque (rom) dans la mémoire. Sous ce terme barbare, j’entends en fait qu’on a besoin de dire au contrôleur de la rom quelle est la zone mémoire de 128 Ko à laquelle on veut accéder, mais également l’endroit où il doit la placer en mémoire. Il est impossible d’accéder à la totalité des 4Mo directement pour la simple raison que l’adresse maximale qu’on peut atteindre avec le système actuel de ciblage d’adresse est F000h : FFFFh, c’est-à-dire 1Mo, alors que la Rom en fais 4. Pour ce faire, il va falloir écrire dans un certain port une certaine valeur suivant l’endroit où nous souhaitons placer nos 128 ko et quelle partie de la rom nous souhaitons charger a cet endroit. Le tableau suivant montre dans quel port écrire pour « mapper » une zone de rom dans la zone mémoire de la graph100 correspondante.
Port d’accueil | Zone mémoire correspondante | Commentaires |
---|---|---|
54h | 0000h - 1FFFh | |
55h | 2000h - 3FFFh | Ne pas utiliser ces ports, car zone mémoire vive |
56h | 4000h - 5FFFh | |
57h | 6000h - 7FFFh | |
58h | 8000h - 9FFFh | |
59h | A000h - BFFFh | |
5Ah | C000h - DFFFh |
Les valeurs à écrire dans ces ports s’étalent de C0h à DFh, C0h ciblant les 128 premiers Ko de la rom, et DFh les derniers (ce qui cible bien 4Mo, 32x128Ko).
C’est elle qui va contenir nos programmes. Elle mesure 1Mo.
Segment | Contenu |
---|---|
0000h - 0FFFh | Zone système |
1000h - 1FFFh | Lecteur A: |
2000h - 2FFFh | Langue en cours d’utilisation |
3000h - 3FFFh | Presque vide |
4000h - FFFFh | Contient les flashs envoyées par l’utilisateur, c’est-à-dire normalement les lecteurs L: à Q: |
On y accède exactement de la même manière qu’on accède à la rom, seule la valeur à envoyer au port change. On y envoie les valeurs de A0h à A7h. A0h mappe les 128 premiers Ko en mémoire, A7h les 128 derniers. La disposition mémoire présentée précédemment est celle de base, à l’acquisition de la calculette. Mais la flash étant réinscriptible, il est possible que des programmes modifient son contenu. Quoi qu’il en soit, si une telle opération est réalisée et que Rom-dos s’en trouve altéré (notamment à la suppression du lecteur A:), le système va de lui-même restaurer la flash dans cet état initial, l’écriture sur la flash est donc sans danger. Mais y écrire n’est pas aussi simple qu’y lire. Car pour y lire, il suffit de faire peek() en C pour accéder aux données qu’on vient de mapper , alors que pour y écrire, un simple poke() ne suffit pas. En fait, les données sur la flash sont protégées en écriture, il faut donc passer par plusieurs étapes avant de pouvoir modifier quoi que ce soit. Il est impératif de savoir que sur la flash, lors d’une écriture, la seule modification possible est de remplacer (en binaire) des 1 par des 0, l’inverse étant physiquement impossible à réaliser sur un bit isolé. La seule possibilité de contourner cet obstacle, est de formater le secteur entier que l’on souhaite modifier, ce qui positionne tous les bit de ce secteur à 1. Une fois cette opération réalisée, on peut écrire ce que l’on veut, les 1 resteront des 1, ou se transformeront en 0, si nécessaire. Cette opération est très délicate, car formater détruit tous les fichiers et données présents dans le secteur. Il faut donc dans une première étape sauvegarder les données en mémoire, puis formater, ensuite modifier les données en mémoire, et enfin réécrire l’intégralité des 64 Ko modifiés. Pour sauvegarder ces données, on peut utiliser l’espace de la ram entre 2000h:0000h et 4000h:0000h, espace qui peut cependant être occupé par des fichiers basic, ce qui entraîne leur perte et le cas échéant des messages d’erreurs lors du prochain arrêt de la calculatrice (au pire la perte totale des fichiers basic).
Considérons donc que le fait de perdre les données importe peu pour le moment, et concentrons nous maintenant sur la manière d’effectuer les formatages et les écritures sur la flash. Pour ce faire, vous devez tout d’abord mapper la zone à écrire en mémoire. Considérons que c’est le lecteur L :, que nous avons mappé en 4000h : 0000 (code à exécuter : outportb(0×56,0xA2) ;). Nous souhaitons maintenant formater le lecteur L: Il nous suffit simplement de le demander au contrôleur de la flash. Pour cela, nous lui donnerons des instructions, par écrit, à des endroits précis du secteur
Code à écrire en asm :
mov ax,0x4000 ;nous plaçons es au début de notre mov es,ax ;secteur mov [es:0xAAA],byte 0xAA ;puis nous écrivons 6 valeurs mov [es:0x554],byte 0x55 ;à des endroits bien précis mov [es:0xAAA],byte 0x80 ;le contrôleur comprendra alors mov [es:0xAAA],byte 0xAA ;que l’on souhaite formater mov [es:0x554],byte 0x55 ;le secteur en cours mov [es:420 ],byte 0x30 ;420 ou une autre valeur, ;peu importe ici ; Début de formatage de la flash
A ce stade il reste encore deux choses à faire. La première est de tester la fin du formatage qui prend quelques secondes. Pour ce faire, on va lire une zone du secteur en format. Ceci ne renverra pas la valeur présente à l’endroit lu, mais l’état d’avancement de l’opération. Si le 6eme bit de l’octet renvoyé est nul, c’est que le formatage est terminé. Voici un exemple en assembleur du test de fin d’opération :
.Attend mov bl,[es:si] ; Demande à la flash deux octets ; de vérification (on lit n’importe mov bh,[es:si] ; où dans le secteur, pas à un endroit xor bl,bh ; spécifique.) and bl,0x40 ; Le 6eme bit est-il mis ? jz .fin ; si oui, la flash est formatée and bl,0x20 ; Sinon on regarde le 5eme bit jz .Attend ; s’il est mis c’est que le formatage ; n’est pas terminé, code en cas d’erreur ; sinon il y a eu une erreur .fin ret
Les exemples précédents sont tous en asm car ces opérations demandent une exécution rapide. Vous pouvez les inclure dans vos programmes en C en prenant soin de modifier leurs syntaxe si besoin, et de rajouter une des directives proposées ci-dessous, selon votre compilateur :
asm {lignes de code assembleur} // Pour Turbo C
Vous pouvez également les re-écrire directement en C, avec des peekb et des pokeb. Mais souvenez vous que chaque secteur ne fait que 64ko et qu’un lecteur (le lecteur L en l’occurrence) mesure 128 Ko. Il nous faut donc par la suite mettre es à 5000h et recommencer les opérations précédentes. Maintenant il serait souhaitable d’écrire sur notre flash vierge. C’est le même type d’opération que le formatage, voici une routine écrivant un octet sur la flash en Assembleur :
mov [es:0xaaa],byte 0xaa ; 3 commandes pour prévenir la flash qu’on mov [es:0x554],byte 0x55 ; souhaite écrire un octet. mov [es:0xaaa],byte 0xa0 mov [es:si],al ; al contient la valeur à écrire, et si pointe ; vers l’offset du secteur où on souhaite écrire
Après ceci, il nous faut encore appeler la routine de vérification, celle présentée plus haut fonctionnant encore dans ce cas. Voici un tableau regroupant les opérations possible à effectuer sur la flash :
1er Cycle | 2ème Cycle | 3ème Cycle | 4ème Cycle | 5ème Cycle | 6ème Cycle | |
---|---|---|---|---|---|---|
Offset/Valeur | Offset/Valeur | Offset/Valeur | Offset/Valeur | Offset/Valeur | Offset/Valeur | |
Ecrire | AAAh AAh | 554h 55h | AAAh A0h | ? ? | - | - |
Formater secteur | AAAh AAh | 554h 55h | AAAh 80h | AAAh AAh | 554h 55h | xxx 30h |
Formater chip | AAAh AAh | 554h 55h | AAAh 80h | AAAh AAh | 554h 55h | AAAh 10h |
Notes :
Sachez enfin que tous les secteurs de la flash mesurent 64 Ko, sauf les 64 premiers Ko qui sont organisés en 4 secteurs de 16Ko, 8Ko, 8Ko, et 32Ko dans l’ordre. Pour plus d’informations sur les fonctionnalités avancées de la flashs, reportez-vous à son manuel (en anglais).
Il est également possible d’accéder à la mémoire par l’intermédiaire de l’interruption 48h. Mais les valeurs à utiliser sont alors différentes. Voici comment fonctionne cette interruption. : Interruption 48h Accès aux disques
Ah = 0
Bl = numéro du segment mémoire dans lequel on veut mapper (0 = 0 ; 1 = 2000h : 0000h ; 2 = 4000h : 0000h...).
Bh ? 6.
Al = numéro de la zone à mapper selon la table suivant
Zone mémoire flash | Numéro dans al |
---|---|
0000h - 1FFFh | 0×40 |
2000h - 3FFFh | 0×42 |
4000h - 5FFFh | 0×44 |
6000h - 7FFFh | 0×46 |
8000h - 9FFFh | 0×48 |
A000h - BFFFh | 0×50 |
C000h - DFFFh | 0×52 |
Zone mémoire rom | Numéro dans al |
---|---|
0000h - 1FFFh | 0×80 |
... | |
3E000h - 3FFFh | 0xBE |
Ah = 1
Bl = numéro du segment mémoire (0 = 0 ; 1 = 2000h : 0000h ; 2 = 4000h : 0000h...).
Bh ? 6.
Retour : Al prend la valeur de la zone mémoire mappée à l’endroit ciblé par Bl, valeur correspondant à celle vue ci-dessus par Ah=0.
Ah = 2
Renvoie dans ax le mot écrit en 0040h : 00C6