Tous le monde connait le dernier des pockets Casio équipé d’un processeur 16 bits (le 80L188EB). Lorsque je me suis lancé dans l’émulation de ce pocket, je pensais naïvement que cela serai assez simple, le processeur étant trés bien documenté.Assez rapidement, j’ai donc réussi à obtenir le boot et tout semblait parfait si ce n’est qu’il indiquait une quantité de mémoire à 0Ko au RESET.
En fait, le Casio ne savait pas calculer !
En traçant les ports d’entrées/sorties du CPU il est rapidement apparu que des appels étaient effectués sur les ports 220h et 221h lors des fonctions de calculs.
J’ai tout d’abord pensé à un FPU ou bien à une puce spécialisée pour gérer la machine virtuelle COMET (le CASL rendu obligatoire par le ministère de l’éducation japonais)… Sans succès.
Alors, au grands maux les grands moyens : désassemblage complet de la ROM, localisation des procédures de calculs flottants et reverse engineering sur les algorithmes utilisés pour l’addition, la multiplication, …
Et là, tout commence à s’éclairer. J’ai isolé plusieurs commandes envoyées par le CPU pour manipuler les nombre flottants au format BCD. Les ingénieurs de chez Casio ont donc codé dans une puce externe les fonctionnalités de manipulation de flottant en BCD car celles ci n’existent pas en natif dans le 80188. Ils y ont été obligé car s’ils avaient développé ces fonctions en natif dans le CPU, les temps de calculs auraient été bien plus important que sur les générations précédentes (PB-1000, PB-2000,VX-3,VX-4). En effet le Toshiba HD61700 de ces pocket comporte un jeux d’instruction manipulant le multi-byte BCD.
Ce problème était à l’époque résolue sur les desktops équipés du 8088 par l’adjonction d’un 8087, mais aucun 8087 n’étant compatible avec le 80L188EB du Z-1 (seul le 80C186EB accepte le 80C187), un mini FPU dédié au format flottant BCD Casio a été implémenté.
Bien, une fois le contexte (à peu prés) déterminé, il fallait donc trouver la liste et les fonctions de chaque commande.
Le Z-1 a 3 zones mémoire de 10h octets servant aux calculs, nous les appellerons X,Y et W:
X : 400h - 40Fh Y : 410h - 40Fh W : 420h - 42Fh Le format est : Mantisse exposant signe 00 00 00 00 00 00 00 00 00
Voir le site de notre ami piotr qui décrit ce format :
J’ai commencé grâce à l’analyse de la ROM à trouver quelques commandes :
41h : Mantisse X - Mantisse Y 10h : X <- 0 11h : Y <- 0 80h : SWAP ( X <-> Y) 0Eh : 0448h: 0448h : Shift Right Mantisse X 04C0h : Mantisse X + Mantisse Y 04C1h : Mantisse X - Mantisse Y 044Ah : 044Ch : 04C2h, 04C3h, 0490h, 0491h, 0499h, 049Ch, 054Eh, 05D0h, 0800h, 0801h,
Une fois codé en binaire, l’ensemble des commande a plus de sens :
0 / 1 Bit 0 : Add / Sub Bit 1 : X / Y charge le registre interne avec X ou Y Bit 2 : Right/Left Sens du shift Bit 3 : no / Shift Bit 4 : Exponent Bit 5 : ??????????? Bit 6 : Mantisse 00 00000000 Add exponent and sign 01 00000001 Sub exponents sign (X-Y) 41 01000001 sub mantisse (X - Y) 43 01000011 sub mantisse (Y - X) 48 01001000 Shift Right and src X 4A 01001010 Shift Right and src Y 4C 01001100 Shift Left 4E 01001110 Shift Left and src Y 90 10010000 Add Exp 1 91 10010001 Sub Exp 1 99 10011001 Shift Right and sub Exp 1 9c 10011100 Shift Left and add Exp 1 C0 11000000 Add Mantisse and src X C1 11000001 Sub Mantisse and src X C2 11000010 Add Mantisse and src Y C3 11000011 Sub Mantisse and src Y D0 11010000 Cpy X to internal register bit 0 : X / Y bit 2 : Write reg bit 3 : exchange reg ??? bit 4 : clear port 221: 04 00000100 Write reg to X 05 00000101 Write reg to Y 08 00001000 exchange reg and X ??? 0E 00001110 exchange reg and X ??? 10 00010000 clear X 11 00010001 clear Y 80 10000000 swap X Y
Donc c’est assez simple. Il y a un registre interne qui peut être chargé et manipulé par un OUT 220h.
Un out 221h permet d’écrire le registre interne sur X ou Y par les commandes 04h ou 05h. La commande 08h permet de faire un swap entre X et le registre interne.
Tous les calculs positionnent aussi les flags Z et C qui sont lu par un IN 220h.
Je tiens à remercie dprtl (voir http://silicium.org/forum/viewtopic.php?f=64&t=31900) qui m’a permis de trouver ou vérifier les différentes commandes en traçant les fonctions sur un vrai Z-1 (eh oui, je n’ai pas encore la bête).
Le seul doute qui subsiste concerne les commandes 0800h, 0801h et 0Eh. Nous n’arrivons pas à les tracer sur le vrai et il reste un petit bug dans l’émulation de ces commandes qui m’a obligé à la mise en place TEMPORAIRE d’un HACK dans l’émulation (oui, je sais, c’est MAL).
Voilà, Il reste encore beaucoup de chose à trouver sur le Z-1, notamment les autres ports I/O, mais un gros morceau à été fait avec la partie calcul.
I AM PURCHASE CASIO FX-890P