Hewlett Packard HP 41CX

English Version
WikipédiA



Une légende parmi les calculatrices programmables.
Cherchez bien dans l'image, une pelure de cacahuète est cachée!

Caractéristiques Les modules d'extension L'imprimante thermique Le lecteur de cartes Le lecteur de codes barres Exemple commenté Le multimètre digital L'unité d'acquisition Le lecteur K7 Programmation MCODE

Une calculatrice que je ne connaissais que de réputation. Je m'attendais à une TI 59 avec des possibilités alphanumériques. Mais c'est tout autre chose: pas de pas de programmes rigides, la gestion de la mémoire est dynamique, coexistance de programmes à la manière de fichiers, les fonctions disponibles dans les modules sont directement accessibles par leurs noms, le clavier est redéfinissable, la mémoire permanente, la machine est facilement extensible et sensiblement plus rapide que la TI-59.

Compacte et bien remplie:

Les modules d'extension

Les logements de modules



Les 4 logements vides
Au dos de la calculatrice on trouve 4 logements pouvant accueillir:
  • Des modules (mémoire, applications)
  • Des périphériques (lecteur de cartes, imprimante)

Deux logements occupés par des modules, l'un est libre pour l'imprimante et l'autre pour le lecteur de cartes
Le module Advantage
Il contient de nombreuses extensions mathématiques facilitant la résolution de problèmes:
  • Calcul matriciel, inversion, déterminant, résolution de systèmes
  • Résolution de f(x)=0
  • Calcul intégral avec précision souhaitée
  • Solution d'équations différentielles
  • Calcul complexe et binaire
  • Statistiques avec régressions selon 5 courbes possibles
  • Calculs financiers d'emprunt ou d'épargne

J'ai écrit un résumé en français du manuel anglais
(format )
que vous pouvez télécharger.


Le module Memory
Il apporte une mémoire de 238 registres supplémentaires (modèle HP82181A). Ils s'ajoutent aux 124 registres de mémoire étendue contenue dans la calculatrice.
Ces registres ne peuvent pas être adressés directement, et les programmes qui y sont stockés ne peuvent pas être exécutés depuis ce module. Son utilité est d'amener un RamDisk pour le stockage permanent de registres, de programmes, de fichiers texte ou tout autre donnée utile.

Manque de chance je n'ai qu'un HP82106A incompatible avec la HP41CX, il apporterait 64 registres à une HP41C.


L'imprimante thermique

L'imprimante thermique dispose de réglages d'intensité, des boutons PRINT et ADVANCE ainsi que d'un sélecteur de mode (MAN, NORM, TRACE) qui qui fixe les informations à imprimer.

Elle apporte également de nombreuses fonctions supplémentaires d'impression de registres, de programmes ainsi qu'un programme de tracé de la courbe d'une fonction.

Dans ce document vous trouverez un résumé des fonctions de l'imprimante.

PRP: print program, le listing d'un exemple du manuel.
L'instruction LIST permet d'imprimer une partie d'un programme.

PRREGX: imprime les registres selon la valeur de X (ici 10,012 pour imprimer de R10 à R12)

CAT 1: liste des programmes en mémoire. On dispose aussi d'autres catalogues (liste des alarmes en cours, liste des modules, liste des fonctions...).
Tracé de la fonction f(x)=1/sqrt(x²+1) ci-dessous
Voilà le listing de la redéfinition d'un caractère.
Au début, on efface X et Y avec 0 ENTER.
Ensuite, on entre la définition binaire de chaque colonne:
  * * * * *     =  1
*           *   =  2
*   *   *   *   =  4
*           *   =  8
*   * * *   *   = 16
*           *   = 32
  * * * * *     = 64
Par exemple, pour la colonne centrale: 1+16+64 = 81.
On entre les définitions avec BLDSPEC.
On place le caractère dans le bufer avec ACSPEC.
Puis l'appui sur ADV lance l'impression.

On utilise une méthode similaire pour imprimer des bitmaps de 43 colonnes de large (c'est la limite de la mémoire tampon).

Ne manquez pas la dernière ligne ou apparaît le petit bonhomme nouvellement défini!


Le lecteur de cartes


Le lecteur de cartes magnétiques se loge au dessus de la calculatrice. On voit une carte prête pour la lecture.

Dans ce document vous trouverez un résumé des fonctions du lecteur.
Périphérique de sauvegarde des données. On distingue 4 types de cartes:
  • Les cartes programme (un programme et ses affectations de touches éventuelles)
  • Les cartes de données (une série contigue de registres)
  • Les cartes d'état (enregistrement de la pile, des flags, etc...)
  • Les cartes de sauvegarde (écriture complète de la mémoire)
D'intéressantes possibilités existent comme:
  • L'exécution automatique, une carte "bootable" en sorte
  • La fusion de programmes (MERGE du BASIC, l'overlay chez d'autres)
  • Le chargement de sous programmes se remplaçant les uns les autres (un peu les DLL avec des swaps RAM/Disque)
  • La possibilité de programmer toutes ces fonctions.


Le lecteur de codes barres

Il permet rapidement l'entrée de programmes, de valeurs dans les registres de données soit en mode direct soit en cours d'exécution. En fait, il possède en gros les capacités du lecteur de cartes magnétiques en lecture.

C'est l'outil idéal pour passer vos programmes d'un PC à la HP41 !



Voici comment:
Tout d'abord on édite le programme sous forme de texte avec une instruction par ligne. J'utilise, comme toujours Quick Editor dont les menus sont redéfinissables. Ceci me permet, depuis l'éditeur, de lancer la compilation, de visualiser les codes barres et de lancer l'émulateur pour tester mon programme.
Ensuite, on lance la compilation en utilisant HP41UC.EXE. Dans la première passe il transforme le texte source en fichier RAW (série d'octets brute). C'est le format utilisé par l'émulateur V41 sous Windows.

Deuxième appel, le fichier RAW est transformé en fichier PS (PostScript) avec les codes barres correspondants. J'ai automatisé la tache avec un fichier BATCH (Cliquer ici pour le visualiser)
Pour finir, on lance GSview (Ghost Script View) pour visualiser le fichier PS. A partir du même programme, on peut imprimer les codes. Sur mon imprimante laser, la sortie est impeccable et lisible sans problème avec le lecteur de la HP 41. La lecture se fait très rapidement, entre une et deux secondes par ligne de barres.
L'exemple ci-contre correspond au programme SUITE ci-dessous:

La fameuse suite qui finit toujours sur 1:
  • Si l'entier est pair on calcule n/2
  • Si il est impair on calcule 3n+1
Le programme indique cobien d'étapes sont nécessaires pour arriver à 1.
Y'a plus qu'à lancer la lecture!!

Vous pouvez lire sur l'affichage:

W: RDY 03



J'ai lu déjà deux lignes et il affiche qu'il est prêt pour la 3è.

Le système permet de s'affranchir des aléas du stockage magnétique et de conserver une trace papier des programmes.


Exemple commenté

Voici un petit programme que j'utilise pour surveiller le compteur de mes pages WEB. Il donne la moyenne des visites par jour depuis son installation (en décembre 2007) ainsi que la moyenne depuis la dernière sauvegarde (ce qui me permet de voir l'impact d'une publication ou modification récente).

Ce programme utilise:

registre contenu registre contenu
r00 compteur actuel r04 compteur sauvegardé
r01 date actuelle r05 date sauvegarde
r02 heure actuelle r06 heure sauvegarde
r03 moyenne visites actuelle r07 moyenne sauvegardée
Pour obtenir la moyenne, on calcule la différence de compteur divisée par la différence de temps. Pour le temps, c'est à la seconde près. Non seulement on a l'écart de jours avec la fonction DDAYS mais j'ajoute une partie décimale avec la différence des heures.
On l'utilise avec:
compteur XEQ WEB

STO 0 STO 1 et STO 2 conservent le compteur, la date et l'heure.
DDAYS calcule l'écart depuis le 15 décembre 2007.
12 HMS- calcule l'écart des heures car le compteur fut mis en place à midi! On divise par 24 et on ajoute aux jours pour un écart décimal précis à la seconde.
On prépare ensuite l'affichage sous la forme "AVRG = xx.xx" (AVRG = average = moyenne), puis on stoppe.

Après l'appui sur R/S, on ouvre le fichier "WEBDATA" en plaçant le pointeur au début (0) avec SEEKPTA.
La séquence 4.007 GETRX récupère les données dans les registres 4 à 7, et on affiche la précédente moyenne (R07) de la manière "OLD = xx.xx".
Un autre appuis sur R/S donne la moyenne depuis cette sauvegarde, donc on recalcule l'écart de temps et de compteur! Cela est affiché sous la forme "LAST = xx.xx".
Pour finir, on peut, par un dernier R/S, sauvegarder les nouvelles données à la place des anciennes. Si on ne le fait pas, les anciennes valeurs restent la référence.
Pour ce faire, 0 SEEKPT remet le pointeur fichier au début (nom du fichier inutile car il est déjà ouvert) et la séquence 0.003 SAVERX sauvegarde les registres 0 à 3.

Avant toute utilisation, il faudrait créer le fichier! Avec la séquence suivante:
"WEBDATA" 4 XEQ CRFLD
Qui crée le fichier WEBDATA contenant 4 registres.
Ensuite, lorsque le programme est chargé, tapez:
compteur XEQ WEBINIT
pour remplir les registres avec le compteur actuel et les données de temps, voyez qu'on se branche sur la séquence de sauvegarde précédente.

Téléchargement: hp41web.zip.
Le fichier contient:
  • WEB.TXT: le fichier source du programme
  • WEB.RAW: le fichier chargeable par l'émulateur V41
  • WEB.PS: le fichier PostScript des codes barres pour une saisie rapide!


Le mutlimètre digital HP 3468B

Il s'agit d'un multimètre (Volts/Ampères/Ohms en continu ou alternatif) qui peut fonctionner seul par l'intermédiaire de son clavier et de son affichage digital...
... ou bien télécommandé par l'intermédiaire de son interface HP-IL! Dans ce cas, la HP-41 peut entièrement le piloter et récupérer les mesures effectuées pour un traitement informatique.
Programme de mesure d'une tension:

Ce programme me permet de mesurer une tension alternative à intervalles régulier, d'en garder la valeur minimale et maximale ainsi que la moyenne. (Sur 1h30, donc 90 mesures, j'ai obtenu un courant allant à peu près de 232V à 238V).

XEQ OBSERVE
routine d'initialisation:

REMOTE: place le multimètre en mode esclave.
"F1R4Z1T1" OUTA: envoit la chaine de commande pour Voltage alternatif (F1) dans la gamme 300V (R4) avec Autozéro (Z1) et mesures en continu (T1).
IND: input data, prend une première mesure et la stocke en R10 (moyenne), R11 (max), R12 (min) et place 1 dans R13 (nombre de mesures effectuées).

La suite programme l'alarme périodique:

"^^MESURE": la routine à éxécuter.
0.01: toute les minutes.
0: pas de date précisée.
TIME 0.01 HMS+: commencer dans une minute!
XYZALM: programme l'alarme.

MESURE
routine qui s'exécute périodiquement:

TONE 9: émet un bip lors de la mesure.
1 ST+ 13: une mesure de plus.
IND ST+ 10: prend une mesure et la cumule.

Ensuite, on compare à R11, si c'est plus, c'est un nouveau maximum et on affiche "MAX "+valeur.
Sinon, on compare à R12, si c'est moins, c'est un nouveau minimum et on affiche "MIN "+valeur.
Sinon, on calcule la moyenne (R10/R13) et on affiche "MOY "+valeur.
Voici l'ensemble avec mon programme qui tourne.

On peut imaginer d'améliorer le système:
  • Avec la fonction OFF, on peut rendormir la HP-41 après chaque mesure pour qu'avec la batterie on puisse réaliser des mesures sur une longue période.
  • Pendant que la HP-41 dort, on peut afficher un résultat sur l'afficheur digital du multimètre (par exemple la moyenne) afin de vérifier l'avancée des mesures (fonction D2+texte envoyé avec OUTA vers le multimètre).
  • On peut aussi relier des thermistances ou photorésistances à l'ohmmètre pour des calculs de température ou d'ensoleillement.


Programme consommation d'un appareil:

Ce programme calcule la consommation d'un appareil en KWH.
Voyez le montage ci-contre: le câble de la prise multiple blanche a été en partie détourné pour que le courant traverse le multimètre. Ainsi on peut mesurer l'ampérage de tout ce qui est branché ensuite. Dans mon premier montage, j'ai utilisé un petit ventilateur.
La routine "CONSO" initialise le programme.
FIX 4 pour un affichage correct des heures.
REMOTE pour mettre le multimètre en mode esclave.
"F6R2Z1T1" pour un courant alternatif (F6) jusqu'à 3A (R2) avec AutoZero (Z1) et mesures en continu (T1).
La routine vous demande ensuite le voltage utilisé (j'ai mis 230), le courant résiduel (en effet, la simple led rouge de la prise multiple consomme déjà 0,0012 A). Pour ceci, c'est à ce moment que je l'allume et j'exécute simplement une lecture du multimètre avec IND pour indiquer la valeur.
On vous demande aussi la fréquence de lecture, j'ai mis 0,0030 pour 30 secondes.
C'est le moment d'allumer l'appareil! Puis R/S pour lancer le calcul.

La routine "AMPERE" est celle qui mesure à la fréquence souhaitée.
Un bip est émis, une mesure est prise avec IND et on retire le courant résiduel (R13) avant d'accumuler la valeur dans R10.
Cette routine s'exécute en gros en 2 secondes.

A tout moment, pour voir la consommation, on peut exécuter la routine "KWH" qui vous affiche le temps passé depuis le début de la mesure:

ainsi que la consommation jusqu'à ce point:


Pour arrêter les mesures, CATALOG 5 vous liste les alarmes programmées, faire R/S sur celle lançant AMPERE, puis Shift C pour l'effacer.


L'unité d'acquisition HP 3421A

Cette unité est avant tout une coquille permettant d'accueillir vos cartes d'acquisition de données selon vos besoins. Elle peut en contenir 3 en tout:
  • Cartes de mesures AC, DC, Ohms
  • Cartes digitales d'entrée sortie 8 bits
Pour ma part je dispose de deux cartes de mesures.

Le panneau frontal est équipé d'entrées permettant une mesure AC, DC ou Ohms même si l'unité ne contient aucune carte.


L'intérieur:

Outre les entrées frontales et le petit panneau LCD, on y trouve:
  • Une batterie, mais la mienne ne charge plus
  • Les connecteurs HP-IL pour une commande par la HP-41
  • Les logements pour trois cartes d'extensions. Je dispose de deux HP 44462B qui peuvent être réglés ainsi:
    • soit 10 entrées AC, DC ou Ohms limitées à 150VA
    • soit 8 entrées et 2 commandes pour fermer des circuits


Il faut régler la tension d'alimentation sur 240V pour la France. Cela se fait sans soudure, mais on doit ouvrir l'appareil et déplacer un connecteur. De même, la fréquence du courant doit être réglée sur 50 Hz. Sur cette image on voit également le connecteur HP-IL ainsi que les 3 panneaux des cartes. L'un est encore libre.


La HP-41 peut accéder individuellement à n'importe quelle entrée des 3 cartes et en obtenir une mesure. Les entrées sont numérotées 0-9 pour la carte #0, 10-19 pour la carte #1 et 20-29 pour la carte #2.
Exemple:
	   alpha DCV13 alpha XEQ OUTA
	      -> envoit la commande DCV13 qui va faire une
		  lecture en courant continu sur
		  l'entrée 3 de la carte 1.
	   XEQ IND
	      -> (IND = Input Data),
		  récupère la donnée lue dans le registre X.
	   
On peut également faire une lecture de plusieurs entrées en même temps!
alpha ACV21-24 alpha XEQ OUTA
	      -> envoit la commande pour une mesure en
		  alternatif des entrées 1 à 4 de la carte 2.
	   XEQ IND -> récupère la valeur lue sur l'entrée 21
	   XEQ IND -> celle de l'entrée 22 ... etc.
	   


Cette unité dispose encore de plusieurs fonctionnalités intéressantes:

Le lecteur de cassettes HP 82161A

Cette unité permet l'enregistrement de fichiers (programmes/données) via l'interface HP-IL.
Elle utilise des micro-cassettes:



Chacune peut stocker 128Ko de données.


Comme tout média de stockage, il faut d'abord l'initialiser avec la commande NEWM (new media) à laquelle on précise le nombre maximal de fichiers qui seront stockés. Ici, une initialisation avec 10 fichiers possibles:

Remarquez le voyant BUSY pendant l'opération de formatage assez longue
Si la cassette est détériorée ou la tête de lecture sale, vous pouvez obtenir ce message d'erreur:


Je m'en sers principalement pour une sauvegarde globale de mes données. L'instruction WRTA (write all) est idéale pour cela.

On place d'abord dans le registre ALPHA le nom du fichier de sauvegarde, je l'ai appelé BACKUP.
Puis, on exécute la commande WRTA qui va sauvegarder complètement la mémoire du HP-41 sur bande (programmes, regsitres, flags, pile...)


On peut ensuite vérifier la présence du fichier sur la bande avec la commande DIR
Le nom BACKUP apparait suivi de WA, c'est donc un fichier "Write all":
Pour récupérer les données, (un changement des piles qui dure trop longtemps peut amener à une perte des données), il suffit de remettre le nom "BACKUP" dans le registre ALPHA et d'utiliser la commande READA (read all).

La programmation MCODE : l'assembleur!

J'ai eu la chance de récupérer un module CLONIX41 qu'Emmanuel C. a bien voulu me garnir ainsi:
  • Page 9: ZENROM, module éditeur de mémoire, sauvegarde/restauration, programmation synthétique
  • Page A: David Assembler, une merveille de facilité pour saisir un programme.
  • Page B: Mainframe label, complément du précédent avec tous les labels officiels de la ROM afin de clarifier les listings
  • Pages C & D : ES 41 Data Base
  • Page F: 512 mots de RAM (pseudo ROM)




Ci-dessus, QuickEditor avec le source d'un programme et les 4 menus programmables qui permettent:
  1. D'assembler
  2. De voir le listing généré
  3. De créer l'image ROM (link)
  4. De tester son programme sous l'émulateur
La préparation d'un programme se fait aisément sur un PC avec le SDK de Warren Furlow.

J'utilise toujours QuickEditor dont les menus sont programmables. Le fichier source est édité dans la fenêtre principale et on fait appel à:
  • A41: l'assembleur (une version A41_32 en 32 bits existe), il génère un listing avec les adresses et les opcodes du programme.
  • L41: le linker (une version L41_32 en 32 bits existe), il génère l'image de la ROM telle qu'elle serait programmée pour la HP.
  • M41: l'émulateur (pas de version 32 bits), un peu spartiate mais très complet avec BreakPoints et suivi pas à pas du programme. Il prend en entrée l'image ROM générée par L41.
  • D41: je ne l'utilise pas, mais c'est un désassembleur de ROM. (version 32 bits disponible)
  • T41: traducteur entre les 3 dialectes d'assembleur possible (pas de version 32 bits). Pour le David Assembleur, on utilise la norme JDA.


Ci dessous l'émulateur avec un point d'arrêt:
La saisie d'un programme peut se faire de deux manières:
Avec ZENROM
grâce à XEQ MCED, on passe sous l'éditeur de mémoire, vous pouvez entrer le programme ci contre en tenant compte des adresses (1ère colonne) et en tapant les codes hexadécimaux des instructions (2è colonne).

Voici l'édition de la première ligne:


Voici mon aide-mémoire de l'affectation des touches:



Avec DAVID ASSEMBLER
grâce à XEQ ASSM, on passe sous l'assembleur. Vous pouvez alors taper votre programme en respectant la norme JDA.

Voici l'édition de la ligne F061:


Voici mon aide-mémoire de l'affectation des touches:

Assembler A41 v4.0 Sat Jul 30 15:29:49 2016
File: AFF.SRC

                            .JDA    
                            .ORG    F000  
F000 01F                    XROM    31                 ; numéro de ROM
F001 002                    FCNS    2                  ; nombre de fonctions
F002 000053                 DEFR4K  [AFF]              ;F053 ; leurs adresses
F004 000085                 DEFR4K  [SWAP23]           ;F085 
F006 000                    NOP                        ; fin de liste (NOP=0)
F007 000                    NOP     
                                                       ; *********************************************
                                                       ;     AFF
                                                       ; affichage d'un caractère
                                                       ; entrée 1xxx XEQ AFF, affiche le caractère xxx
                                                       ; *********************************************
                            .FILLTO 004F  
                            .NAME   "AFF" 
F050 086                    #086                       ;"F"
F051 006                    #006                       ;"F"
F052 001                    #001                       ;"A"
F053 0F8    [AFF]           READ    3                  ; récupère X=1xxx dans C
F054 27C                    RCR     9                  ; ramène les trois chiffres xxx sur S&X
F055 106                    A=C     S&X                ; sauvegarde xxx en A
F056 130010                 LDIS&X  10                 ; sélectionne une zone vide
F058 270                    RAMSLCT 
F059 1300FD                 LDIS&X  0FD                ; et le périphérique écran
F05B 3F0                    PRPHSLCT 
F05C 046                    C=0     S&X                ; remet C à zéro
F05D 01B                    JNC     [FIRST]            ;+3    F060 
F05E 260    [BOUCLE]        SETHEX                     ; incrémente C en hexadécimal
F05F 226                    C=C+1   S&X   
F060 2A0    [FIRST]         SETDEC  
F061 1A6                    A=A-1   S&X                ; décrémente A en décimal
F062 3E3                    JNC     [BOUCLE]           ;-4    F05E ; jusqu'à la fin : en sortie C est la conversion
                                                       ; hexadécimale de A
F063 3A8    [FIN]           WRIT    14                 ; écrit le caractère C=hex(xxx) sur l'écran
F064 046                    C=0     S&X   
F065 3F0                    PRPHSLCT                   ; abandonne le périphérique écran
F066 1FD00C                 ?NCXQ   037F  
F068 060                    POWOFF                     ; attend une action
F069 000                    NOP     
                                                       ; *********************************************
                                                       ;     SWP23
                                                       ; echange les 2è et 3è chiffres de la mantisse
                                                       ; *********************************************
                            .FILLTO 007F  
                            .NAME   "SWP23" 
F080 0B3                    #0B3                       ;"3"
F081 032                    #032                       ;"2"
F082 010                    #010                       ;"P"
F083 017                    #017                       ;"W"
F084 013                    #013                       ;"S"
F085 0F8    [SWAP23]        READ    3                  ; récupère X dans C
F086 11A                    A=C     M                  ; copie la mantisse dans A
F087 3FA                    LSHFA   M                  ; décale A vers la gauche
F088 19C                    R=      11                 ; 11è chiffre
F089 0A2                    C<>A    @R                 ; copie ancien 10è sur le 11è
F08A 39A                    RSHFA   M                  ; décale deux fois A vers la droite
F08B 39A                    RSHFA   M     
F08C 3D4                    R=R-1                      ; 10è chiffre
F08D 0A2                    C<>A    @R                 ; copie ancien 10è sur le 11è
F08E 0E8                    WRIT    3                  ; renvoit le résultat dans X
F08F 3E0                    RTN     
0 Warning(s)
0 Error(s)
END


La sauvegarde d'un programme assembleur se fait grâce à ZENROM. La sauvegarde se fait par paquets de 5 mots stockés dans un registre.

1: On a besoin de connaître l'adresse du registre 00, elle est stockée dans le registre système "c". On tape [RCL] [.] [C] et on obtient un affichage particulier: 2: On doit décoder ce registre, pour cela on tape [XEQ] DECODE, les 3 chiffres soulignés sont l'adresse de R00, ici 19C:
3: Ensuite, on bascule sous MCED et on utilise la commande SVE (pour save), si on veut sauvegarder mon programme ci-dessus, on complète les adresses ainsi, puis [R/S]: 4: La commande nous demande ensuite l'adresse du premier registre de sauvegarde, on tape alors 19C, puis [R/S]:


Entre les adresses F000 et F08F, nous avons hex(90) mots, c'est à dire 144. Puisqu'ils sont stockés par groupe de 5, il nous faudra 29 registres de données pour conserver ce programme. C'est à dire de R00 à R28. On utilisera alors les commandes de sauvegarde sur bande magnétiques habituelles pour garder une trace du programme.



La restauration d'un programme se fera sous MCED avec la fonction GET.

Lancer MCED, touche RCL
La machine affiche GET A_ _ _:A _ _ _. Remplissez avec: GET A19C:d029 (touche [.] pour faire apparaître le "d").
Appuyer sur [R/S]
La machine affiche ADR: _ _ _ _. Remplissez avec ADR: F000. Puis [R/S].


Sauvegarde des 29 registres en mémoire étendue


Voici la liste des actions à faire:
  • ALPHA MCODE 29 XEQ CRFLD (crée un fichier MCODE de 29 registres)
  • 000.028 XEQ SAVERX (écrit de R00 à R28)
Récupération des 29 registres depuis la mémoire étendue


Voici la liste des actions à faire:
  • ALPHA MCODE 0 XEQ SEEKPTA (ouvre le fichier, pointeur au début)
  • 000.028 XEQ GETRX (récupère de R00 à R28)


Sauvegarde des 29 registres sur bande magnétique


Voici la liste des actions à faire:
  • ALPHA MCODE 29 XEQ CREATE (crée un fichier MCODE de 29 registres)
  • ALPHA MCODE 0 XEQ SEEKR (positionne le pointeur au début)
  • ALPHA MCODE 000.028 XEQ WRTRX (écrit de R00 à R28)
  • ALPHA MCODE XEQ VERIFY (si on veut vérifier le fichier)


Récupération des 29 registres depuis la bande magnétique


Voici la liste des actions à faire:
  • ALPHA MCODE 0 XEQ SEEKR (ouvre et positionne le pointeur au début)
  • ALPHA MCODE 000.028 XEQ READRX (lit de R00 à R28)


Un petit jeu : TWIX.

Origine :
J'ai trouvé ce jeu dans une version pour HP67/97 "Super Twix" écrit par David V Smith.


La règle :
le but est de transformer une série de 9 chiffres en une autre avec un nombre limité de mouvements. Traditionnellement, on tente de transformer la série 123456789 en 987654321.


Comment jouer :
On écrit la série de 9 chiffres de départ, puis XEQ TWIX, on arrive sur le plateau ci-contre


Les différents mouvements

(remarquez le score qui augmente à chaque fois!)


Exchange Left : le 1 et le 2 à gauche sont échangés.



Rotate Left : décalage à gauche, le 2 vient en dernière position.



Exchange Ends : le 1 et le 2 aux extrémités sont échangés.



Rotate Right : décalage à droite, le 1 revient en première position.



Exchange Right: le 8 et le 9 à droite sont échangés.



Premier défi

lancez le jeu avec
111182222 XEQ TWIX
et tentez d'obtenir 222281111 en 14 coups!





Téléchargement


Le fichier twix.zip contient:
  • ATWIX.SRC: le fichier source.
  • ATWIX.LST: le listing avec codes.
  • ATWIX.OBJ: fichier objet prêt à linker
  • ATWIX.ROM: image ROM du jeu.
                                                       ;       13 12 11 10  9  8  7  6  5  4  3  2  1  0
                                                       ; A=     x  x  N  N  N  N  N  N  N  N  N  D  S  S
                                                       ; NNN... les 9 chiffres
                                                       ; D = caractère de séparation
                                                       ; SS le nombre de coups
                                                       ; B utilisé pour sauvegarder A
                                                       ; C utilisé pour un peu tout.
                                                       ; aucun autre registre, aucun flag.
                            .JDA    
                            .ORG    F000  
F000 01F                    XROM    31    
F001 001                    FCNS    1     
F002 00000A                 DEFR4K  [TWIX]             ;F00A 
F004 000                    NOP     
F005 000                    NOP     
                            .NAME   "TWIX" 
F006 098                    #098                       ;"X"
F007 009                    #009                       ;"I"
F008 017                    #017                       ;"W"
F009 014                    #014                       ;"T"
                                                       ; initialisation
F00A 0F8    [TWIX]          READ    3                  ; copie X dans C
F00B 11A                    A=C     M                  ; sa mantisse dans A
F00C 39A                    RSHFA   M                  ; 9 chiffres en position 11 à 4
F00D 006                    A=0     S&X                ; exposant à zéro: nombre de coups
F00E 2A0                    SETDEC                     ; tous les calculs en décimal.
                                                       ; affichage
F00F 130010 [DISP]          LDIS&X  10    
F011 270                    RAMSLCT                    ; zone RAM fictive
F012 1300FD                 LDIS&X  FD    
F014 3F0                    PRPHSLCT                   ; périphérique Ecran
F015 0AE10E                 C=A     ALL                ; récupère les 9 chiffres +score
F017 21C                    R=      2     
F018 350                    LD@R    D                  ; code fictif pour séparateur
F019 1BC                    RCR     11                 ; le premier chiffre en position
F01A 0A0                    SLCTP   
F01B 35C                    R=      12                 ; pour la boucle
F01C 0E0    [L1]            SLCTQ   
F01D 21C                    R=      2     
F01E 010                    LD@R    0     
F01F 0D0                    LD@R    3                  ; prépare le code 03N dans C
F020 3E8                    WRIT    15                 ; copie vers l'écran
F021 2FC                    RCR     13                 ; chiffre suivant
F022 0A0                    SLCTP   
F023 3D4                    R=R-1                      ; un tour de moins
F024 394                    ?R=     0                  ; jusqu'à zéro
F025 3BB                    JNC     [L1]               ;-9    F01C 
F026 130000                 LDIS&X  0                  ; quitte l'écran
F028 3F0                    PRPHSLCT 
F029 3C8    [WAIT]          CLRKEY                     ; attend une touche
F02A 3CC                    ?KEY    
F02B 3F3                    JNC     [WAIT]             ;-2    F029 
F02C 220                    C=KEY                      ; touche en 4-3
F02D 33C                    RCR     1                  ; touche en 3-2
F02E 166                    A=A+1   S&X                ; augmente le nombre de coups
F02F 08E                    B=A     ALL                ; sauvegarde A !
F030 0AE                    A<>C    ALL                ; la touche en A 3-2
F031 21C                    R=      2                  ; pointe sur XS
F032 0D0                    LD@R    3                  ; met la valeur 3
F033 376                    ?A#C    XS                 ; le code touche se termine par 3 ?
F034 3A0                    ?NCRTN                     ; si oui, fin du jeu (ligne contenant ENTER et <-)
F035 356                    ?A#0    XS                 ; le code se termine par zéro?
F036 39F                    JC      [WAIT]             ;-13   F029 ; non, donc touche invalide !
F037 0F53C0                 ?NCXQ   [ACTION]           ;F03D ; sous programme traitant les différents cas
F039 3C8    [KOFF]          CLRKEY                     ; attend que la touche soit relevée
F03A 3CC                    ?KEY    
F03B 3F7                    JC      [KOFF]             ;-2    F039 
F03C 29B                    JNC     [DISP]             ;-45   F00F ; et retour à l'affichage
                                                       ; ********************************
                                                       ; execute l'action selon l'une des
                                                       ; 5 touches de la première ligne
                                                       ; ********************************
F03D 38E    [ACTION]        RSHFA   ALL                ; le nibble haut de la touche dans XS
F03E 15C                    R=      6     
F03F 050                    LD@R    1     
F040 0D0                    LD@R    3     
F041 1D0                    LD@R    7     
F042 210                    LD@R    8     
F043 310                    LD@R    C                  ; les codes des 5 touches du haut
F044 376                    ?A#C    XS                 ; égal à C (touche C0=LN)
F045 0B3                    JNC     [XRIGHT]           ;+22   F05B ; oui! échange des 2 de droite
F046 33C                    RCR     1     
F047 376                    ?A#C    XS                 ; égal à 8 (touche 80=LOG)
F048 113                    JNC     [RRIGHT]           ;+34   F06A ; oui! rotation droite
F049 33C                    RCR     1     
F04A 376                    ?A#C    XS                 ; égal à 7 (touche 70=SQR)
F04B 093                    JNC     [XENDS]            ;+18   F05D ; oui! échange des extrémités
F04C 33C                    RCR     1     
F04D 376                    ?A#C    XS                 ; égal à 3 (touche 30=1/X)
F04E 0BB                    JNC     [RLEFT]            ;+23   F065 ; oui! rotation gauche
F04F 33C                    RCR     1     
F050 376                    ?A#C    XS                 ; égal à 1 (touche 10=S+)
F051 360                    ?CRTN                      ; non! mauvaise touche... (impossible normalement)
                                                       ; *******************************
                                                       ; (S+) échange les deux de gauche
                                                       ; *******************************
F052 0DC                    R=      10    
F053 0EE    [XCOMM]         C<>B    ALL                ; récupère A dans C
F054 10E                    A=C     ALL                ; puis dans A
F055 33C                    RCR     1     
F056 102                    A=C     @R                 ; ex a11 dans a10 (ou a4 dans a3)
F057 37C                    RCR     12    
F058 3DC                    R=R+1   
F059 102    [GETR]          A=C     @R                 ; ex a10 dans a11 (ou a3 dans a4)
F05A 3E0                    RTN     
                                                       ; *******************************
                                                       ; (LN) échange les deux de droite
                                                       ; *******************************
F05B 01C    [XRIGHT]        R=      3     
F05C 3BB                    JNC     [XCOMM]            ;-9    F053 
                                                       ; *********************************
                                                       ; (SQR) échange les deux extrémités
                                                       ; *********************************
F05D 0EE    [XENDS]         C<>B    ALL                ; récupère A dans C
F05E 10E                    A=C     ALL                ; puis dans A
F05F 17C                    RCR     6     
F060 19C                    R=      11    
F061 102                    A=C     @R                 ; ex a3 dans a11
F062 23C                    RCR     2     
F063 01C    [GET3]          R=      3     
F064 3AB                    JNC     [GETR]             ;-11   F059 ; ex a11 dans a4
                                                       ; *****************************
                                                       ; (1/X) rotation vers la gauche
                                                       ; *****************************
F065 0EE    [RLEFT]         C<>B    ALL                ; récupère A dans C
F066 10E                    A=C     ALL                ; puis dans A
F067 3FA                    LSHFA   M                  ; décale la mantisse, mais un chiffre perdu!
F068 13C                    RCR     8                  ; positionne l'ex premier chiffre en 3
F069 3D3                    JNC     [GET3]             ;-6    F063 ; et va récuperer ce chiffre perdu
                                                       ; *****************************
                                                       ; (LOG) rotation vers la droite
                                                       ; *****************************
F06A 0EE    [RRIGHT]        C<>B    ALL                ; récupère A dans C
F06B 10E                    A=C     ALL                ; puis dans A
F06C 39A                    RSHFA   M                  ; décale la mantisse, mais un chiffre perdu!
F06D 17C                    RCR     6                  ; ex dernier chiffre en 11
F06E 19C                    R=      11    
F06F 353                    JNC     [GETR]             ;-22   F059 ; et va récupérer ce chiffre perdu


J'en ai fait une version sous Android à l'aide de AppInventor.

Télécharger l'application TWIX.


Depuis le 15 décembre 2007