Agir sur l'écran de la HP49g

par HPThifu



Introduction

Bon, nous pouvons attaquer le problème: comment agir sur l'écran de notre HP49g, afin de dessiner dessus ? Car l'inconvénient majeur du RPL normal (User-RPL) est d'être particulièrement lent, et un programme qui aurait besoin de remplir tout l'écran en noir (sans passer par un GROB) au moyen d'une boucle FOR...NEXT prendrait plusieurs secondes...

Il y a une solution qui permet d'agir sur l'écran instantanément (enfin, assez rapidement pour que notre oeil ne puisse pas voir le processus, mais seulement le résultat): c'est d'utiliser l'assembleur.

L'assembleur est un langage proche de la machine, dit "de bas niveau", et de ce fait beaucoup plus rapide que le User-RPL. C'est un langage compilé, c'est-à-dire traduit en suite de 0 et de 1 intelligibles par la machine. Le programme qui effectue cette traduction est appelé un compilateur, ou un assembleur.

Dans cette documentation, vous trouverez de multiples indications pour agir directement sur l'écran de votre HP, ainsi que des programmes d'exemples : ...le tout bien sûr commenté :)

Ce dont vous avez besoin: Bonne programmation !

1. Préparer votre HP

Allumez votre HP.

Appuyez sur MODE, puis sur F4 ('DISP') et vérifiez que la case 'Full Page' n'est PAS cochée. Cette étape est très importante, car l'assembleur intégré dans votre HP, appelé MASD, est très sensible, et une ligne vide en trop, voire un espace mal placé, risquent de provoquer une erreur. Enlever l'option 'Full Page' permet d'éviter ce risque.

Entrez 256, puis ATTACH. Cette manipulation permet d'attacher une librairie intégrée à votre HP, appelée 'Development Lib' (accessible depuis le menu 'APPS', tout en bas, après 'CAS menu'). Cette librairie permet l'utilisation de l'assembleur, intégré lui aussi, appelé MASD.

Vérefiez que vous êtes en mode RPL, sinon appuyez sur 'MODE' et remplacez 'Algebraic' par 'Rpl'.

2. Fonctionnement de l'affichage

2.1 Pixels et octets

L'écran de la HP49g est formé d'unités élémentaires appelées pixels. Un pixel peut être allumé (noir) ou éteint (blanc). La résolution, c'est-à-dire la taille de l'écran est de 131 pixels en largeur et 64 pixels en hauteur, soit 131*64=8384 pixels au total. On désigne par un 1 un pixel allumé, et par un 0 un pixel éteint.

Par exemple: 10101100 désigne:

Un élément unitaire 0 ou 1 s'apelle un BIT. On groupe souvent les BITs par quatre (un quartet) ou par huit (un octet). La HP travaille avec des octets pour l'affichage à l'écran, et avec des quartets dans son processeur interne :). D'ailleurs, un octet est composé de 2 quartets.

Or, la largeur de l'écran est de 131, ce qui n'est pas un multiple de 8. C'est pourquoi la HP gère un écran virtuel de 136 pixels, soit 136/8=17 octets. Les 5 pseudo-pixels n'existent matériellement pas, et sont donc uniquement là pour obtenir un nombre entier d'octets.

2.2 Mémoire graphique

Continuons: 17 octets par ligne, et 64 lignes, cela nous fait 1088 octets, soit un peu plus d'un kilooctet (1 kilooctet = 1024 octets). Donc la HP possède une zone de 1088 octets dans sa mémoire, réservée à l'affichage. On appelle cette zone la mémoire graphique, tout simplement.

Plusieurs dizaines de fois par seconde, la HP parcourt cette zone mémoire, et rafraîchit l'écran: elle part du début, et avance octet par octet, en appliquant une règle simple:
1: j'allume le pixel, 0:j'éteins le pixel

De façon pratique, vous pouvez déjà vous apercevoir que:

2.3 Utilisation de l'hexadécimal

Pour écrire les octets, nous n'allons pas utiliser la notation des BITs, car il faudrait entrer 1088 chiffres pour remplir l'écran, ce qui prend de la place, et est très long. Nous allons donc utiliser une notation adéquate: la base hexadécimale.

En effet, considérons un quartet: bbbb (b signifiant BIT). b pouvant valoir 0 ou 1, le nombre de combinaisons possibles est 24, soit 16 combinaisons, d'où l'appellation de base hexadécimale.

Voici la liste des valeurs, de O à 15:
Binaire Décimal Hexadécimal Binaire Décimal Hexadécimal
0000 0 0 1000 8 8
0001 1 1 1001 9 9
0010 2 2 1010 10 A
0011 3 3 1011 11 B
0100 4 4 1100 12 C
0101 5 5 1101 13 D
0110 6 6 1110 14 E
0111 7 7 11111 15 F


Cela nous permet de désigner chaque combinaison de pixels dans un quartet.
Exemple:
0110 : 6 :
1010 : A :

Oui, mais comment représenter un octet ? C'est très simple: puisque un octet se comporte de 2 quartets, on note l'octet sous la forme de deux quartets. Je m'explique:
On a l'octet: 01101010
Il se compose de 0110 et de 1010
Or, 0110 est noté 6 et 1010 est noté A
Donc, notre octet est noté: 01101010 : 6A :
De même, 01001101 : 0100 et 1101, soit 01001101 : 4D :


Bon, munis de notre petit bagage informatique, nous allons enfin :) pouvoir aborder le premier programme: effacement de l'écran.

3. Prog 1: Effacement de l'écran

Le but de la maneuvre est d'écrire un programme qui efface rapidement l'écran. Pour cela, nous allons récupérer l'adresse de la mémoire graphique, puis nous allons y écrire des octets 00000000. Enfin, nous utiliserons une instruction SysRPL (qui est un langage intermédiaire entre l'assembleur et le User-RPL) pour attendre que vous appuyiez sur une touche.

Prêt ? On y va !

Entrez le programme dans l'éditeur de texte de votre HP ('APPS' puis '9. Text Editor'), en respectant les sauts de ligne et les Majuscules/minuscules.

!NO CODE %Directives au compilateur MASD
!RPL %
%
:: %Début du proramme
TURNMENUOFF %Instruction SysRPL évitant d'être gêné par les menus
%
CODE %Début de la partie assembleur
GOSBVL 0679B %Savegarde l'état interne de la HP
P=0 %
%
D0=8068D %Récupère l'adresse de la mémoire graphique
C=DAT0 A %
D0=C %D0 contient l'adresse du début de la mémoire graphique
%
LA 0000000000000000 %A contient donc 16 quartets de valeur 0, soit 16*4=64 BITs 0
%On efface donc par série de 64 pixels
LC(2) (((136*64)/4)/16)-1 %On intialise le compteur de boucles. On a donc un écran de 136*64 pixels
%soit (136*64)/4 quartets, que l'on remplit par paquets de 16 quartets.
%On a donc au bilan ((136*64)/4)/16 opérations à répéter
%et on soustrait 1 pour des raisons internes à la HP :)
%
( %Début de boucle
DAT0=A 16 %On colle à l'adresse D0 de la mémoire graphique le contenu de A
D0=D0+16 %On avance le pointeur de 16 quartets, comme sur un vieux 45 tours :)
C=C-1 B %On décrémente le compteur de tours
UPNC %On recommence la boucle si C est supérieur ou égal à 0
) %Fin de boucle
%
GOVLNG 05143 %Rétablit les paramètres internes de la HP
END CODE %Fin du code assembleur
%
WaitForKey %Instruction SysRPL attendant que vous pressiez une touche
DROP %On fait le ménage sur la pile
DROP %
%
; %Fin de programme
@ Indique à MASD que le fichier à compiler s'arrête ici.

Bon, vous avez réussi à rentrer ce court programme ? Il faut maintenant le compiler.
Dupliquez la chaîne de caractères que vous venez de taper, et stockez-en une dans une variable (cf Manuel HP pour plus de renseignements). Puis, avec l'autre exemplaire au nivean 1 de la pile, tapez 'ASM' et validez. MASD apparaît brièvement, et vous vous retrouvez avec un objet bizarre sur le niveau 1. Stockez-le dans une variable, puis allez retrouver cette variable, qui doit être du type 'Programme'. Il ne vous reste plus qu'à l'exécuter, et à admirer...

Si l'on veur noircir l'écran, il suffit de remplacer LA 0000000000000000 par LA FFFFFFFFFFFFFF.

Pour afficher un pixel sur deux, (valeur 1010 : A), il suffit de remplacer LA 0000000000000000 par LA AAAAAAAAAAAAAAAA.

Vous pouvez donc afficher ce que vous voulez, en quartets. Dernier exemple: pour afficher un motif revenant périodiquement sur 4 quartets:



On décompose en quartets, ce qui donne: 1101=D; 0110=6; 1010=A; 1011=B. Donc 1101011010101011 se note D6AB.
Vous pouvez donc remplacer LA 0000000000000000 par LA D6ABD6ABD6ABD6AB


J'espère que cette documentation vous a permis de commencer à entrevoir les immenses possibilités de la programmation en assembleur.

la suite arrive bientôt ...



Pour tous commentaires, encouragements, ou critiques :(, envoyez-moi un e-mail