LEX 'LOWCLEX' * (c) Copyright PPC Paris 1986 ************************************************** * * Lex "LOWCLEX" : fichier Lex didactique È l'usage * des membres de PPC-Paris qui veulent en savoir * plus sur l'assembleur du HP71. * * Fonction prÅsente : * LOWC$ ( ) * convertit une chaÑne de caractÉres en * minuscules (pendant de UPRC$ pour les * majuscules). * * Note : ne pas rentrer les commentaires dans le * fichier source. Cela prend de la place, et du * moment que vous avez ces commentaires dans votre * Journal prÅfÅrÅ... ************************************************** * * Id du Lex. * '#' indique qu'il s'agit d'un nombre en * hexadÅcimal. * analogie : l'Id est au HP71 ce que le premier * numÅro d'un XROM est È la HP41. L'Id * identifie le fichier Lex. * 5C (92 en dÅcimal) est parmi les Id de scratch * allouÅs par HP. C'est È dire les Id * utilisables pour nos essais. * Si jamais une fonction est d'intÅrÁt suffisant * PPC-Paris lui attribue un numÅro dans l'Id * de PPC-Paris (#E1, ou 225), ce qui est * gÅnÅralement le cas. * Les Id de scratch sont : 5C, 5D et 5E * C'est ceux-ci que vous utiliserez pour vos * premiers essais * ID #5C * * La table de message * Le '0' indique qu'il n'y a pas de table de * messages. * Nous verrons µa une autre fois, peut-Átre. * En tous cas, sachez que la construction d'une * table de messages est fastidieuse, et qu'il * vaut mieux la laisser È des programmes (il * en existe un, en Basic) * MSG 0 * * La routine d'interception de poll * cf ci-dessus : le '0' indique qu'il n'y a pas * de routine d'interception de poll. * POLL 0 * * La partie constituant l'en-tÁte du fichier est * finie. Maintenant, il y a les descriptions des * fonctions, au nombre de une ici : * * * L'ordre ENTRY indique l'adresse ou commencera * l'exÅcution de la fonction. * ENTRY lowc * * CHAR #F indique qu'il s'agit d'une fonction. * (et non d'un "statement"). * CHAR #F * * KEY est suivi du nom de la fonction. Le '$' est * le seul moyen pour le systÉme Basic de savoir * qu'il s'agit d'une fonction alphanumÅrique. * Le nom doit Átre limitÅ È 8 caractÉres (y * compris le '$'). * KEY 'LOWC$' * * Vient enfin le numÅro de token de la fonction, * c'est È dire le deuxiÉme numÅro d'un XROM HP41 * pour garder l'analogie ci-dessus. * TOKEN 28 * * ENDTXT = fin de la partie obligatoire du Lex. * C'est la fin de la dÅclaration des noms et des * caractÅristiques des fonctions prÅsentes dans ce * Lex. * ENDTXT * * C'est ici que commence vÅritablement le Lex. * * * Ici, nous dÅfinissons les noms des routines * internes HP que nous allons utiliser : * ADHEAD EQU #181B7 D=AVMS EQU #1A460 POP1S EQU #0BD38 RANGE EQU #1B07C * * Juste avant le point d'entrÅe de la fonction * (dÅfini par ENTRY), il y a la description des * paramÉtres. Il y a ici : * NIBHEX 4 Une chaÑne alphanumÅrique NIBHEX 1 Un paramÉtre au minimum NIBHEX 1 Un paramÉtre au maximum * * Le point d'entrÅe de la fonction. C'est ici oË * arrive le systÉme, quand il va essayer d'Åvaluer * LOWC$("AREUH"). * * A cet instant lÈ, nous aurons : * P=0 * Mode = Hex * 4 niveaux de pile (RSTK) disponibles * la chaÑne ("AREUH") est sur la Math-Stack * C(S) contient le nombre de paramÉtres (ici 1) * D0 contient le pointeur programme * D1 contient le pointeur sur la Math-Stack * D(A) = AVMEMS * * Le premier travail È faire sera de sauvegarder * D0, pour le restituer en bon Åtat È la fin. * lowc * * D0 est sauvegardÅ dans la pile de retours, car * nous n'allons pas beaucoup l'utiliser dans ce * Lex. Si µa n'avait pas ÅtÅ le cas, nous aurions * sauvÅ D0 dans FUNCD0 qui est prÅvu pour µa. * CD0EX RSTK=C * * Il faut maintenant regarder ce que nous avons * sur la Math-Stack. L'utilitaire POP1S est fait * pour cela : il examine le "stack-header", et * en dÅduit la longueur de la chaÑne. En sortie, * D1 = adresse de 'H' * A(A) = 10 (= 2x5 caractÉres) * GOSBVL POP1S * * D1 pointe sur le 'H'. Nous allons le faire * pointer sur le 'A'. * L'adresse ainsi obtenue sera sauvegardÅe dans * R1 pour Átre utilisÅe par ADHEAD. * La chaÑne sera parcourue de 'A' È 'H'. * * | #00000 | * | | * | | * |---------| * (1) -> | Stack | * | header | * |---------| * (2) -> | H | * |---------| * | U | * |---------| * | E | * |---------| * | R | * |---------| * | A | * |---------| * | |<- (3) * | | * | | * | | * | #FFFFF | * * (1) : avant le POP1S * (2) : aprÉs le POP1S * (3) : aprÉs le C=C+A * CD1EX C(A) := adr. de 'H' C=C+A A C(A) := adr. juste avant 'A' D1=C D1 := adr. juste avant 'A' R1=C R1 := dÅbut de la chaÑne * * Nous allons maintenant calculer la longueur en * octets, par une division par 2 de A(A). * A(A)=xxxxxxxxxxxlllll * Nous allons faire une divison par 2, c'est È * dire un dÅcalage È droite de 1 bit. Mais alors, * le premier 'x' va interfÅrer avec 'lllll' (on ne * peut dÅcaler que le registre complet). * B=0 M premier x:=0 (entre autres) B=A A B(W)=x0000000000lllll BSRB B(A)=longueur en octets * * B(A) est maintenant la longueur de la chaÑne en * octets. Cela va nous servir de compteur de * boucle. * FOR B(A)=B(A) TO 1 STEP -1 * * * La boucle qui suit est d'un type que vous voyez * souvent dans mes programmes : * Vous voulez compter n fois * * LC(5) n * GOTO b20 * b10 * * * b20 C=C-1 A * GONC b10 * * Si si, essayez, µa marche ! * GOTO lowc20 lowc10 D1=D1- 2 D1 := adr. exacte du 'A' A=DAT1 B A(B) := 'A' LCASC 'ZA' } A(B) dans l'intervalle GOSBVL RANGE } 'A'..'Z' ? GOC lowc20 Non. On ne fait rien LC(2) 32 Conversion en majuscule A=A+C B DAT1=A B Et remise en mÅmoire lowc20 B=B-1 A DÅcrÅmentation du compteur GONC lowc10 Saut si non fini * * La boucle est maintenant finie. * D1 pointe sur 'h' * R1 pointe juste avant 'a' * * Il faut renvoyer ces informations au systÉme, * par l'intermÅdiaire de la routine ADHEAD. * Mais auparavant, vous vous souvenez que nous * avons mis D0 dans la pile de retours ? * Il faudrait peut-Átre penser È le rapatrier... * C=RSTK D0=C * * ADHEAD attend dans D(A) la valeur de AVMEMS * GOSBVL D=AVMS * * Pour l'explication exacte de ce ST=0, voir la * documentation de ADHEAD. * ST=0 0 GOVLNG ADHEAD * * Et voilÈ 74 octets d'assembleur HP71. Alors, µa * ne vous donne pas, vous aussi, l'envie de vous * y mettre ? * END