logo

Objectif
A première vue
Le schéma
L'alimentation
Le microcontrôleur
Le synthétiseur
Les ROMs
Code et memory map
Cartouche AVR
Cartouche CPLD
Convertir les sons
Créer le ROM
Circuits imprimés
Le code

Ne pouvant trouver de documentation claire à propos du format des ROMs (même dans le brevet), mis à part pour les "magic bytes" dans un post de Lord Nightmare. J'ai pris le temps de recopier le listing en assembleur dans un fichier OO Calc (téléchargeable ici). J'ai commenté la majeure partie du code concernant les fonctions principales telles que les lectures dans les ROMs, la communication avec le synthétiseur, et le mode "Spell". Il reste encore le code du jeu du pendu et du "Say it", qui ne m'intéressait pas particulièrement.

Attention, la majeure partie des instructions LDP ont été omises par Texas Instruments dans le listing ! Certainement pour "miner" le code et empêcher d'avoir une bête copie fonctionnelle.

LDX, TCY: Charger X, Y
CLA: Mettre A a zéro
TAM, TMA: Transférer A en RAM et inversement
TMY: Transférer la RAM dans Y.
XMA: Intervertir A et la RAM
TAMIYC: Transférer A en RAM et incrémenter Y.
ACAAC: Ajouter a A
SBIT, RBIT: Set bit, Reset bit.
YNEC: Incrémenter Y si différent de la valeur
SETR, RSTR: Set ligne R #Y, Reset ligne R #Y.
TKA: Lire les lignes K.
TDO: Charger le PLA.
...

Je rappelle que le jeu d'instructions du TMS1000 est trouvable ici.

En analysant le code, j'ai pu comprendre comment les phrases étaient formées et quels ROMs étaient sollicités à quel moment.

Il y a différents modes (jeux) disponibles, mais le plus connu et celui sur lequel je me suis basé, celui où une liste de 10 mots est choisie aléatoirement en interne, et chacun de ces mots est énoncé avant de demander à l'utilisateur de l'écrire correctement. Une fois ces 10 mots passés, le score est donné puis une nouvelle liste est lancée.

Quand la dictée est allumée, ce mode est choisi par défaut au niveau A (4 niveaux sont disponibles : A, B, C et D) et seuls les ROMs internes sont utilisés. Il y a une touche spéciale pour passer à la cartouche (j'en parlerai après...).

Le nombre de mots est lu depuis le ROM à une adresse fixe, c'est une valeur 8 bits, il ne peut donc y avoir qu'un maximum de 255 mots dans un niveau.
Le compteur 12 bits interne qui sert de timeout pour la mise en veille est utilisé comme seed pour générer la liste de 10 mots.
Ce seed est tronqué pour être inférieur au nombre total de mots (routine DECLOOP).
La liste est remplie avec 10 valeurs commençant donc à ce nombre. Si on dépasse le nombre total de mots, on repart à 0 (routine RPLOOP).
Cette liste "linéaire" est ensuite mélangée en intervertissant les valeurs 2 par 2 (routine RSCRAM).

Une fois cette liste constituée, on attend que le joueur appuie sur la touche "GO" (ou passe à un autre mode, la liste reste en RAM dans tous les cas).

CartridgeQuand le jeu est démarré, les choses ce compliquent. Ca va paraître confus mais c'est juste, restez avec moi.
Les données du mot sont lues depuis le ROM à partir du numéro de mot stocké dans la liste précédemment constituée en RAM.
Pour arriver à ces données, un pointeur 16bits correspondant au niveau choisi est lu à une adresse fixe.
Ce pointeur mène à une liste de pointeurs, qui correspondent à chaque mot du niveau. Il est lu et le numéro du mot multiplié par 2 (les pointeurs font 2 octets) y est ajouté pour tomber sur son pointeur. Ce nouveau pointeur est suivi et on tombe enfin sur les données orthographiques du mot.

L'orthographe du mot est lu octet par octet et stocké en RAM. Comme les lettres ne sont codées que sur seulement 6 bits, le bit 6 est utilisé pour indiquer la dernière lettre (+0x40). Je rappelle qu'un mot ne peut faire au maximum que 8 caractères, je ne suis pas responsable de ce qui peut arriver si on en met plus ! Par exemple, pour le mot "MAISON" (voir les codes PLA), on trouvera:

0C 00 08 12 0E 4D

Immédiatement après ces données se trouve un dernier pointeur vers les données audio, qui ne seront pas lues par le microcontrôleur mais par le synthétiseur. Ce pointeur est néanmoins utilisé pour la prochaine étape. On peut fournir plus d'un pointeur pour former des phrases si besoin. La liste de pointeurs est terminée avec la valeur 0x0001.

Link list:
RAM Page 6 Page 7
0 Pointeur 1
1
2 Pointeur 2
3
4 Pointeur 3
5
6 Pointeur 4
7
8 Pointeur 5
9
10 Pointeur 6
11
12 Pointeur 7
13
14 Pointeur 8
15

Une "link list" est constituée en RAM pour former la phrase "Spell mot". Pour cela, la première entrée est fixée à l'adresse en ROM du mot "Spell", et la seconde à celle du dernier pointeur lu, c'est à dire le mot choisi. Le microcontrôleur traite ensuite cette link list en commandant au synthétiseur de lire ces deux mots.

Imaginons ensuite qu'on se trompe d'orthographe, le microcontrôleur sait que c'est le premier essai, il efface la link list et en prépare une nouvelle pour dire "Wrong, try again". On pourrait croire que cette phrase est dite d'une traite et il ne faudrait pas de link list, mais il se trouve que le mot "Wrong" est aussi utilisé pour énoncer le score. "Wrong" et "Try again" sont deux mots séparés dans le ROM, pour ainsi économiser de la place. Il y a donc encore 2 adresses dans la link list.
La link list est traitée à nouveau, le flag d'essai est passé à 1, et le joueur est invité une seconde fois à écrire le mot.

Imaginons qu'on se trompe encore, le microcontrôleur sait que c'est le second essai et donne alors la bonne orthographe. Une nouvelle link list est faite pour dire "Wrong, the correct spelling of mot is...". On se retrouve ici avec 4 adresses dans la link list : "Wrong", "The correct spelling of", le mot, et "is". Une fois la liste traitée et énoncée, la bonne orthographe du mot est lue en RAM et chaque lettre est dite. Puis on passe au mot souvent...

De multiples pointeurs sont utilisés pour les mots difficilement intelligibles tels que "isle". Pour ce mot, on entend la phrase "Spell isle, as in island", soit 3 pointeurs: "isle", "as in" et "island". "As in island" n'est pas un mot entier car "Island" est aussi utilisé comme mot dans une autre liste. Tout est fait pour économiser l'espace ! Notez que dans la link list il y a bien 4 pointeurs, avec le "Spell" au début.

Quand le score est énoncé, 5 pointeurs se retrouvent dans la link list: "Here is your score", chiffre, "Right", chiffre, "Wrong".

La link list peut stocker un maximum de 8 adresses. Je ne suis pas non plus responsable de ce qui peut arriver si on excède cette limite !

Concernant les cartouches (c'est à dire le ROM externe), la routine ADD8 permet d'ajouter ou non un décalage de 0x8000 à l'adresse à laquelle on veut accéder, pointant ainsi en ROM interne ou dans la cartouche. Notez bien que la cartouche n'est utilisée que pour les mots, tout le reste (phrases) reste dans le ROM interne. C'est pour cela qu'on a des "Spell embrasser" lorsqu'on branche une cartouche Française dans une dictée anglaise...
Lorsqu'on appuie sur le bouton "Select module", la liste des 10 mots est refaite.

Grâce au code, j'ai aussi pu assembler une grande partie de la memory map de la RAM, ainsi que des ROMs internes (voir les feuilles correspondantes dans le fichier OOffice).

On peut s'apercevoir, entre autres, que les valeurs 8 bits ne se retrouvent pas sous forme de 2 mots consécutifs dans la même page de RAM, mais dans deux pages en parallèle. Par exemple, le buffer d'affichage du VFD se trouve dans les pages 0 (MSB) et 1 (LSB).

Les pages 2 et 3 contiennent le buffer pour l'orthographe correcte du mot, ainsi que le compteur pour la mise en veille et la génération de nombres aléatoires.

Les pages 4 et 5 contiennent la liste de mots pour le jeu (leur numéro, pas leur adresse), ainsi que le nombre total de mots dans le niveau sélectionné.

Les pages 6 et 7 sont utilisées pour la link list, et peuvent contenir un maximum de 8 adresses 16 bits. Ce sont les seules valeurs 16 bits stockées en RAM.

Concernant le ROM, on peut trouver quelques adresses autour des appels à MEMADDR. Par exemple on trouve que les pointeurs vers les données LPC pour les lettres commencent à 0x000C car dans NOSTRANS on ajoute 12 (0x0C) au code PLA de la lettre avant de passer l'adresse au synthétiseur.

Memory map des ROMs Anglaises

Adresse Taille (octets) Description
0 1 Nombre de mots dans le niveau A
1 1 Nombre de mots dans le niveau B
2 1 Nombre de mots dans le niveau C
3 1 Nombre de mots dans le niveau D
4 2 Pointeur vers liste des mots niveau A
6 2 Pointeur vers liste des mots niveau B
8 2 Pointeur vers liste des mots niveau C
A 2 Pointeur vers liste des mots niveau D
C 34 Pointeur vers le LPC des lettres A~Z
40 2 Pointeur vers le LPC de l'apostrophe
42 14 Pointeur vers le LPC des chiffres 0~9
56 2 ?
58 2 Pointeur pour "That is correct"
5A 2 Pointeur pour "You are correct"
5C 2 Pointeur pour "That is right"
5E 2 Pointeur pour "You are right"
60 2 Pointeur pour "(Now) spell"
62 12 ?
6E 2 Pointeur pour "Say it"
70 2 Pointeur pour "I win"
72 2 Pointeur pour "You win"
74 2 Pointeur pour "Here is your score"
76 2 ?
78 8 Pointeurs pour 4 tonalités (4 bips)
80 128 Table de lettres aléatoires

Le reste contient les tables de mots, orthographes et données LPC...

 

Memory map des cartouches (universel)

Adresse Taille (octets) Description
0 1 Nombre de mots dans le niveau A
1 1 Nombre de mots dans le niveau B
2 1 Nombre de mots dans le niveau C
3 1 Nombre de mots dans le niveau D
4 2 Pointeur vers liste des mots niveau A
6 2 Pointeur vers liste des mots niveau B
8 2 Pointeur vers liste des mots niveau C
A 2 Pointeur vers liste des mots niveau D
C 2 Magic bytes (0xAAAA)

Le reste est disponible pour les orthographes et données LPC...

footer
symbol symbol symbol symbol symbol