DC @MINIFONTE 812CF % adresse de la minifonte SAVE %-----------------------------------------------------------------------------% % Récupération de l'adresse de la chaîne et vérification des arguments % %-----------------------------------------------------------------------------% % En sortie : % % R1a = adresse de la chaîne % % D1 pointe sur le prologue de la chaîne % %-----------------------------------------------------------------------------% C=DAT1.A ?C#0.A { % erreur "pas assez d'arguments" LOAD LC 00201 GOVLNG 266C6 } D1=C R1=C.A % R1a contient l'adresse de la chaîne A=DAT1.A LC 02A2C ?C=A.A { % erreur "bad argument type" LOAD LC 00202 GOVLNG 266C6 } %-----------------------------------------------------------------------------% % Calcul de la taille du GROB % %-----------------------------------------------------------------------------% % Utilisation des registres : % % Aa = nombre de caractères lus sur la ligne courrante % % Ba = nombre de caractères de la plus grande ligne trouvée % % Cw = caractères lus % % Dw est utilisé pour faciliter les tests de retour chariots % % D0 = nombre de lignes (utiliser D0 comme compteur, c'est pas banal !) % % D1 pointe sur les caractères à lire % % R2a = longueur de la chaîne (nombre de caractères*2) % %-----------------------------------------------------------------------------% % Initialisation LC 0A0A0A0A0A0A0A0A D=C.W % 0A = retour chariot D1+5 C=DAT1.A C-5.A R2=C.A % lecture de la taille de la chaîne D1+5 A=0.A B=0.A D0=A D0+1 % au moins une ligne ! % 1ère étape : puisque le nombre de caractères n'est pas nécessairement un % multiple de 8, il faut traiter quelques caractères différement... on utilise % pour cela le champ WP P=C.0 ?P=0 { % pas besoin de faire la première étape si P=0 ! P-1 C=DAT1.WP % récupération des caractères à lire CD1EX C+P+1 CD1EX % on les saute... { ?C=0.P -> .QUARTET_0 % si le 1er quartet du caractère est 0. % pas un retour à la ligne A+1.A P-1 P-1 UPNC EXIT *.QUATET_0 % le premier quartet du caractère est un 0 P-1 % on regarde le second quartet ?C=D.P -> .NEWLINE % si le deuxième quartet est un A % pas un retour à la ligne A+1.A P-1 UPNC EXIT *.NEWLINE % le caractère est un retour à la ligne D0+1 ?A<=B.A { B=A.A } A=0.A P-1 UPNC } P=0 } % 2ème étape : ce coup-ci on utilise un champ W ! C=R2.A CSR.A C-1.A SKIPC { RSTK=C % sauvegarde du compteur de boucle dans la RSTK C=DAT1.16 D1+16 % cette boucle est semblable à la première, mais P est incrémenté au lieu % d'être décrementé, ca évite de le remettre à 0 { ?C=D.P -> .QUARET_A A+1.A P+1 P+1 UPNC EXIT *.QUARET_A P+1 ?C=0.P -> .NEWLINE2 A+1.A P+1 UPNC EXIT *.NEWLINE2 D0+1 ?A<=B.A { B=A.A } A=0.A P+1 UPNC } C=RSTK C-1.A UPNC } % ne pas oublier que la dernière ligne peut être plus grande que les autres ! ?A<=B.A { B=A.A } % Pour la troisième étape : on écrit un retour chariot supplémentaire après % la chaine, en sauvegardant dans RSTK la valeur écrasée C=DAT1.B RSTK=C LC 0A DAT1=C.B %-----------------------------------------------------------------------------% % Reservation du GROB % %-----------------------------------------------------------------------------% % En sortie : % % D0 pointe sur le premier caractère de la chaîne % % R0a = adresse du GROB % % R1a = adresse de la chaîne % % R2a = taille de la chaîne (nombre de caractères * 2) % % R3a = hauteur du GROB en pixels % % R4a = largeur du GROB en quartets % %-----------------------------------------------------------------------------% CD0EX C+C.A D=C.A C+C.A C+D.A R3=C.A % R3a = nombre de lignes * 6 D=C.A C=0.A A=B.A R4=A.A % R4a = taille en caractères de la plus grande ligne ?ABIT=0.0 { A+1.A } % la taille d'une ligne d'un GROB doit être multiple de 8 % simple multiplication de Aa par Da, resultat dans Ca { D+D.A ASRB.A ?ABIT=0.0 { C+D.A } ?A#0.A UP } C+10.A % taille pour stoquer la largeur et la hauteur du GROB RES.STR % reservation D0-10 LC 02B1E DAT0=C.A % écriture du prologue d'un GROB D0+10 C=R3.A DAT0=C.A % écriture de la hauteur du GROB D0+5 C=R4.A A=C.A ?ABIT=0.0 { A+1.B } R4=A.A % R4a = nombre de quartets par ligne C+C.A C+C.A DAT0=C.A % écriture de la largeur du GROB D0+5 %-----------------------------------------------------------------------------% % Ecriture des caractères dans le GROB avec la minifonte % %-----------------------------------------------------------------------------% % utilisation des registres pour la boucle sur les lignes : % % Da = adresse de la minifonte % % D1 pointe sur les caractères de la chaîne % % R3a (hauteur du GROB) est utilisé comme compteur % % RSTK = D0 = adresse du premier quartet de la ligne en cours dans le GROB % %-----------------------------------------------------------------------------% % Initilisation CD0EX D0=C RSTK=C C=R1.A D1=C D1+10 LC(5)@MINIFONTE D=C.A % Boucle sur les lignes { C=R3.A C-6.A SKIPNC { EXIT2 } R3=C.A % Boucle sur les caractères d'une ligne { % lecture de deux caractères A=DAT1.A D1+4 LC 0A ?C#A.B { % Si le premier des deux caractères est un retour chariot D1-2 GOTO .FIN_LIGNE } % Ca = adresse de la bitmap du premier caractère dans la fonte C=0.A C=A.B B=C.A C+C.A C+B.A C+C.A C+D.A % Sauvegarde de D0 dans la RSTK, et D0 pointe sur la bitmap du premier % caractère CD0EX RSTK=C % On passe au second caractère ASR.A ASR.X % Si le second caractère est un retour chariot LC 0A ?C#A.B { GOTO .ECRIRE_UN_CHAR } % Aa = adresse du second caractère dans la fonte C=0.A C=A.B C+C.A A=C.A C+C.A A+C.A C=D.A A+C.A % On échange le contenu de Da (adresse minifonte) et R4a (taille ligne) CR4EX.A D=C.A % Lecture de la bitmap du premier caractère C=DAT0.6 % Lecture de la bitmap du second caractère, décalée d'un quartet A-1.A D0=A A=DAT0.7 % Ecriture des deux carcatères à la fois, pour les six lignes A=C.P % on réunit les deux bitmaps de la première ligne P=6 CSR.WP B=C.A % on fout la bitmap du premier caractère dans Ba C=RSTK D0=C % on récupère D0 DAT0=A.B % et on écrit C+D.A D0=C % on passe à la ligne suivante ASR.WP % on décale la bitmap du second caractère P=0 A=B.P DAT0=A.B % etc... C+D.A D0=C ASR.W BSR.A A=B.P DAT0=A.B C+D.A D0=C ASR.A BSR.A A=B.P DAT0=A.B C+D.A D0=C ASR.A BSR.A A=B.P DAT0=A.B C+D.A D0=C ASR A BSR.B A=B.P DAT0=A.B % On reéchange le contenu de Da et de R4a CDEX.A A=C.A CR4EX.A CDEX.A % On retourne sur la première ligne des caractères écrits dans le GROB C-A.A A+A.A A+A.A C-A.A D0=C D0+2 % on passe aux caractères suivants UP *.ECRIRE_UN_CHAR % La même chose qu'avant mais ici on n'écrit qu'un caractère au lieu de 2 D0-1 A=DAT0.7 % lecture de la bitmap du caractère ASR.B C=D.A CR4EX.A D=C.A % echange de Da et R4a C=RSTK D0=C % recuperation de D0 DAT0=A.B P=6 ASR.W ASR.W B=A.A % on fout la bitmap dans Ba P=1 A=0.P P=0 % on en profite pour mettre A1 à 0 C+D.A D0=C DAT0=A.B % on fait quand même des écritures sur un champ B pour unifomiser BSR.A A=B.P % etc... C+D.A D0=C DAT0=A.B BSR.A A=B.P C+D.A D0=C DAT0=A.B BSR.A A=B.P C+D.A D0=C DAT0=A.B BSR.B A=B.P C+D.A D0=C DAT0=A.B CDEX.A A=C.A CR4EX.A CDEX.A C-A.A A+A.A A+A.A C-A.A D0=C D0+2 *.FIN_LIGNE C=RSTK RSTK=C % on récupère l'adresse du début de la ligne dans le GROB AD0EX D0=A % et l'adressee du début du char dans le GROB ACEX.A RSTK=C % qu'on sauve dans la RSTK C-A.A % calcule le nombre de quartets déjà écrits dans la ligne A=R4.A C=A-C.A % nombre de quartets restant à écrire dans la ligne C-1.A SKIPC { P=15 LC 5 % compteur de lignes dans Cs P=C.0 % on va écrire par bloc de 16 quartets, plus le modulo 16 A=0.W % va servir pour écrire du blanc CSR.A B=C.A % on sauvegarde dans Ba { % écriture par bloc de 16 quartets C-1.A SKIPC { DAT0=A.16 D0+16 C-1.A UPNC } DAT0=A.WP % écriture des quartets restants % passe à la ligne suivante A=R4.A C=RSTK C+A.A RSTK=C D0=C % on a utilisé Aa, il faut le remettre à 0 A=0.A C=B.A C-1.S UPNC } P=0 } % il faut enlever ce qu'on avait mis dans la RSTK C=RSTK } % On passe à la ligne de texte suivante C=RSTK A=R4.A A+A.A C+A.A A+A.A C+A.A D0=C RSTK=C UP } % on enleve ce qu'on avait mis dans la RSTK C=RSTK % on restaure l'octet après la chaîne qu'on avait écrasé pour mettre un % retour chariot D1-2 C=RSTK DAT1=C.B % et on quitte en posant le GROB sur la pile... LOAD A=R0.A GOVLNG 03A86 @