Un nouveau modèle, le Casio FX-890P/Z-1/Z-1GR

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.

This entry was posted in Uncategorized. Bookmark the permalink.

One Response to Un nouveau modèle, le Casio FX-890P/Z-1/Z-1GR

  1. Pingback: Stephen

Leave a Reply

Your email address will not be published. Required fields are marked *