lundi 26 novembre 2012

"Ce nombre est-il premier ?"... avec une HP-28S

La HP-28S fut la première calculatrice graphique Hewlett-Packard. C'est celle que j'ai failli avoir pendant mes années lycée, à la place de la CASIO PB-1000. Les deux machines étaient positionnées à des prix comparables en haut de gamme, et elles étaient donc en concurence frontale sur ce marché d'avant 1990. En réalité, je pense qu'elles s'adressaient à un public sensiblement différent : la ROM très riche de la HP la rendait immédiatement attrayante pour un étudiant ou un ingénieur généraliste ; alors que la CASIO, selon moi, était plutôt conçue pour un informaticien. Peut-être que ma vie aurait été différente si j'avais fait le choix de la HP-28S ?

Il serait difficile de parler de la HP-28S sans citer Paul Courbis et Sébastien Lalande (http://www.courbis.fr/Voyage-au-centre-de-la-HP28-c-s.html) : leur boulot de rétro-ingénierie sur cette calculette très "fermée" est énorme. À partir de la documentation technique du HP-71, entre autres, ils ont réussi le miracle de repousser les limites logicielles et matérielles de la HP-28S. La publication de leur bouquin, en 1989, lui ouvrait les mêmes possibilités que la PB-1000 : l'accès au langage machine et les interfaces d'entrées/sorties (port RS-232 bricolé).

Si vous avez lu mon article précédent, vous connaissez une partie des raisons de mon choix en faveur de la PB-1000. Vingt-cinq ans plus tard, après avoir longuement testé la HP-28S, c'est sans hésitation que je maintiens la PB-1000 sur la plus haute marche du podium des meilleures calculatrices des années 80 ! Si vous n'êtes pas d'accord, vous pouvez donner vos arguments dans la zone des commentaires ci-dessous :-)

Une des principales difficultés de la HP-28S, c'est son ergonomie. J'ai eu beaucoup de mal à m'y faire. Le simple fait que la ROM soit très chargée, avec des programmes pas toujours indispensables, rend les fonctions essentielles plus difficiles d'accès. Par exemple, il faut passer par un menu pour accéder aux fonctions trigonométriques et logarithmiques. Pour la programmation, à moins de connaître par coeur les commandes et de les taper en toutes lettres, la navigation dans ces menus hiérarchiques devient vite lourdingue.

Le langage RPL a été inspiré, de loin, par LISP et surtout par FORTH. Du coup, c'est structuré, et la fameuse instruction GOTO n'est pas implémentée. Cela dit, à mon faible niveau d'expérience avec le RPL, j'estime qu'il n'est pas spécialement plus lisible que le BASIC. Pire, les séances de debugging sur HP-28S sont affreusement laborieuses. Du coup, il vaut mieux éviter les gros programmes. Par voie de conséquence, on aurait tendance à multiplier les petits sous-programmes qui s'appellent entre eux (notion similaire à des fichiers indépendants). Mais attention, ça peut vite devenir le bordel dans le nommage et l'organisation hiérarchique utilisateur !

La HP-28S et son clavier alphabétique

Voici une implémentation "naïve" de mon programme en RPL :

<< -> N
  << N \/ IP 'J' STO
     IF N 2 / FP 0 ==
     THEN 2
     ELSE 3 'I' STO
       WHILE I J <=
       REPEAT
         IF N I / FP 0 ==
         THEN 0 'J' STO
         ELSE I 2 + 'I' STO
         END
       END
       IF 0 J ==
       THEN I
       ELSE 1
       END
     END 'I' PURGE 'J' PURGE 440 0.5 BEEP
  >>
>>

- '->' correspond à l'affectation d'une variable locale (touche rouge et 'U')
- les symboles '<<'et '>>' sont les délimiteurs de programme
- '\/' correspond à la racine carrée (touche rouge et '-')
- '<=' est le symbole inférieur ou égal (touche rouge et 'S')

Le test sur le nombre 524 287 s'execute en 33 secondes environ, avec cette version non optimisée de mon programme, sur le CPU Saturn 4 bits cadencé à 1 MHz de la HP-28S. C'est plus lent que les dernières CASIO 8 bits que j'ai testées ! Cela dit, comme l'avaient découvert Courbis et Lalande, la HP-28S d'origine est "underclockée", probablement pour économiser les piles. Par ailleurs, on m'a fait remarquer dans les commentaires ci-dessous que le fait d'utiliser la commande STO dans une boucle est une mauvaise idée (décalages mémoire). Il est donc préférable d'exploiter la pile dans les programmes RPL.

4 commentaires:

  1. Pas d'accord pour le PB-1000 :) C'est le 71B le meilleur des années 80 : clavier très agréable, basic, forth, assembleur, 256k ram possible avec modules, possibilités de commander d'autres périphériques avec une boucle HP-IL, lecteur de cartes magnétiques, lecteur de codes barres et le tout beaucoup moins encombrant qu'un PB 1000 déplié ! Avec un module Math on inverse tranquillement des matrices réelles ou complexes 40*40? ....
    FRED

    RépondreSupprimer
  2. La HP-71B est une machine mythique qui a toujours été affreusement chère : plus du double du prix de la PB-1000. Si on y ajoute quelques options, ça fait mal ! D'où la réputation de calculatrice de "fils à papa". Pour ce prix exorbitant, il ne faut pas oublier qu'on n'a qu'un petit écran de 22 caractères. Quant aux périphériques HP, ils ont certainement été utiles à certains, mais ils restent rares. On peut aussi remarquer que le suivi par HP de cette gamme laisse à désirer : disparition rapide de l'interface HP-IL, et aussi du Basic, du Forth...

    RépondreSupprimer
  3. Pour les rares qui travaillent encore sur la 28S, et pour reprendre un moment de nostalgie, j'en profite pour préciser une chose d’intéressant:
    comment dire..
    Quand on stock une donnée dans une nouvelle variable, la HP28S va décaler toute la ram pour y stocker la nouvelle valeur.. en première position de la ram.. En gros, plus la mémoire est pleine, plus la calculatrice rame (c'est la cas de le dire pour stocker une nouvelle valeur. il est donc fortement déconseillé d'utiliser la fonction STO dans un programme, et encore moins dans une boucle..
    Pour vous en persuader essayez de faire une boucle du style for x = 1 to 100 x 'varx' sto next
    le plus simple est d'utiliser le stockage volatile, qui vient se loger en gaut de la ram, ce qui évite d'avoir à la décaler.. par exemple: << 50 -> X << X >> >> mais ca oblige a ouvrir des << en cascade
    Donc, le plus fun et le plus rapide est d'utiliser directement la pile, avec utilisation des commandes SWAP,OVER, PICK, ROLL, ROT, ROLLD, etc..
    Je viens de reprendre l'exemple en haut en utilisant la pile.. sans changer l'algo, c'est à dire que le même nombre de boucle sera effectué dans ce programme revisité:
    Au final, Le test sur le nombre 524 287 s'execute en un peu moins de 18 secondes sur la 28S et en un peu moins de 9 secondes si le programme "speed" aura été lancé avant :-)
    Sympa non?

    << DUP \/ IP
    IF OVER 2 / FP 0 ==
    THEN
    DROP2 2
    ELSE 3
    WHILE DUP2 >
    REPEAT
    IF 3 PICK OVER / FP 0 ==
    THEN
    SWAP DROP 0 SWAP
    ELSE
    2 +
    END
    END
    IF OVER 0 ==
    THEN
    3 ROLLD DROP2
    ELSE
    3 DROPN 1
    END
    END
    440 0.05 BEEP
    >>

    st33x@free.fr
    Toujours présent pour parler HP :-)

    RépondreSupprimer
  4. Merci pour cette optimisation ! Je me doutais bien que mon code RPL pouvait être arrangé. Le STO qui décale toute la RAM, je crois bien l'avoir lu quelque part, mais je ne l'avais pas enregistré.

    RépondreSupprimer