CODINGLA BIBLE DU CPC 6128

La bible du CPC 6128 : 2.03.00 Utilisation des routines du système d'exploitation (!)
Le CPC contient plusieurs centaines de routines ou fonctions dont certaines sont très utiles et parfaitement utilisables par les programmeurs. On trouve par exemple de telles routines pour l'interrogation du clavier, pour sortir un caractère sur l'écran, pour gérer les fenêtres ou pour commander l'imprimante. Malgré la masse de fonctions dont dispose le système d'exploitation, il y a cependant des choses que le CPC ne sait pas faire de lui-même. C'est ainsi qu'il manque par exemple la possibilité de sortir le contenu de l'écran, texte ou graphisme sur une imprimante connectée au système.

Cette possibilité appelée 'Hardcopy', nous allons vous la montrer dans deux exemples. Dans le premier exemple il s'agira d'un hardcopy de texte uniquement, qui fonctionne avec n'importe quelle imprimante connectée. La seconde routine de hardcopy permet l'impression de tous les caractères, y compris les caractères graphiques du CPC. Les images réalisées en graphisme haute résolution peuvent également être imprimées avec cette routine. Nous avons choisi comme imprimante la NLQ 401. Cette imprimante bon marché est, en ce qui concerne son jeu de caractères de commande, étonnamment compatible avec les imprimantes Epson MX/RX/FX. Les deux programmes tournent donc également sans adaptation sur des imprimantes Epson (et sur toutes les autres imprimantes compatibles).

A la fin de ce chapitre, vous ne trouverez pas uniquement deux routines de hardcopy rapides mais vous aurez également une première approche des routines du système d'exploitation.
Pour sortir le contenu de l'écran sur une imprimante connectée, il faut faire lire les caractères ligne par ligne sur l'écran et les sortir. Du fait de la structure spéciale de la Ram vidéo, il n'est malheureusement pas possible de lire les caractères directement.

A travers le 'détour' par une routine du système d'exploitation, il est cependant possible de déterminer quel caractère se trouve dans l'emplacement actuel du curseur.
Cette routine (TXT RD CHAR, &BB60) transmet le caractère dans l'accumulateur et met le flag carry lorsqu'un caractère a été trouvé. Si par contre aucun caractère du jeu de caractères du CPC ne figure dans l'emplacement du curseur, alors l'accumulateur contient 0 et le flag carry est nul.
Il faut en outre une routine qui nous permette de positionner le curseur, de façon à ce que nous puissions lire les caractères les uns après les autres. Cette fonction est exécutée par TXT SET CURSOR, &BB75. Lorsque cette adresse est appelée, le contenu du registre H est interprété comme colonne et celui de L comme ligne. L'emplacement d'écriture suprérieur gauche peut donc être ainsi adressé par &0101.

Il se pose ici cependant une petit problème. Après que nous ayons fait parcourir toute la surface de l'écran à notre curseur, avec l'interrogation de l'écran, il faudrait qu'il revienne ensuite dans son emplacement initial. Il nous faut donc pour cela, avant le premier positionnement du curseur, déterminer et ranger l'emplacement du curseur.
Cela peut se faire grâce à TXT GET CURSOR, &BB78. Après avoir appelé TXT GET CURSOR le double registre HL contient la position actuelle du curseur. Il nous faut ranger cette valeur et la restaurer à la fin du hardcopy.

Les caractères obtenus grâce à TXT RD CHAR doivent être sortis sur l'imprimante. Nous pouvons utiliser à cet effet MC SEND PRINTER dont l'entrée est en &BD31. Le caractère figurant dans l'accumulateur est sorti sur le port d'imprimante avec tous les signaux handshake nécessaires.
MC SEND PRINTER attend toutefois que l'imprimante soit prête à recevoir. C'est MC BUS Y PRINTER, &BD2E, qui nous permet de constater si c'est le cas. Si l'imprimante n'est pas prête à recevoir, si elle n'est pas allumée ou si elle n'est même pas connectée, MC BUSY PRINTER revient avec un flag carry mis. Dans ce cas, elle doit être appelée à nouveau, jusqu'à ce que le flag carry soit annulé. Le caractère voulu peut alors être sorti.

Il peut cependant également arriver qu'un hardcopy une fois lancé ne doive pas être imprimé jusqu'au bout. L'opération peut être interrompue en appuyant sur la touche 'DEL'. Mais pour cela, il nous faut pouvoir examiner si cette touche est enfoncée. Si KM TEST KEY, &BBIE, est appelée avec un code de touche valable dans l'accumulateur, après exécution de cette routine, le flag zéro est nul si la touche correspondante est enfoncée. Sinon le flag zéro est mis.

Ainsi avons-nous en fait toutes les routines système nécessaires pour écrire une routine de hardcopy. Mais nous nous rendrons compte au plus tard lorsque nous aurons commencé à écrire notre programme, que nous ne savons absolument pas si, au moment du hardcopy, il s'agit de représenter 20, 40 ou 80 caractères par ligne. Bon, on pourrait décider que ce hardcopy ne fonctionne qu'en mode d'écran x. Mais ce serait une limitation peu élégante.

SCR GET MODE avec entrée en &BC11 nous communique avec l'accumulateur et les deux flags carry et zéro, dans quel mode écran le CPC se trouve actuellement. Nous pouvons ainsi réaliser un hardcopy avec le nombre de caractères qui convient, en fonction des informations ainsi obtenues.
Mais venons-en maintenant au programme lui-même. Les lecteurs n'ayant pas d'assembleur peuvent utiliser le programme Basic imprimé à la fin de ce chapitre. Il contient les deux programmes de hardcopy en lignes de Data.

BB78 ;GETCRS EQU #BB78
BB75 SETCRS EQU #BB75
BB60 ;RDCHAR EQU #B860
BD2E ;TSTPTR EQU #8D2E
BD31 ;PRTCHR EQU #BD31
BC11 ;GETHOO EQU #BC11
BB1E ;TSTKEY EQU #BB1E
A100 CD78BB call getcrs ;ranger ancienne position curseur
A103 2264A1 LD (OLDPOS),HL
A106 CD11BC call getmod ;chercher mode écran
A109 17 RLA ;nombre de caracteres/20
A10A 3263A1 LD (MODE),A ;et ranger
A10D 210101 LD hl,#0101 ;dans angle supérieur gauche
A110 2266A1 LD (crspos),hl ;le curseur
A113 3A63A1 LL1 LD A,(MODE)
A116 47 LD B,A ;1,2 OU 4 fois
A117 0E14 loop ld c,20 ;20 caractères par ligne
Al19 C5 LLOOP PUSH BC
A11A E5 PUSH HL
A11B CD75BB call setcrs ;placer le curseur
A11E E1 POP HL
A11F CD60B8 call rdchar ;et déterminer
A122 C1 pop bc ;le caractère
A123 3802 jr c,GOOD ;caractère valable?
A125 3E20 LD A,32 ;sinon Sortir
A127 CD58A1 GOOO CALL PRTOUT ;espace
A12A E5 PUSH HL
A12B C5 PUSH BC
A12C 3E42 ld a,66 ;ESC enfoncée?
A12E CD1EBB CALL TSTKEY
A131 C1 POP BC
A132 E1 POP HL
A133 201C JR NZ,EXIT ;Oui, fin
A135 24 WEITER INC H
A136 0D DEC C
A137 20E0 jr NZ,lloop ;20 caractères imprimés?
A139 10CC djnz loop ;ligne entière?
A13B 3EOD ld a,#0d ;sortir CR/LF
A13D CD58A1 CALL PRTOUT
A140 3E0A LD A,#0A
A142 CD58A1 CALL PRTOUT
A145 2A66A1 ld hl,(crspos) ;déterminer
A148 2c inc l ;position curseur
A149 2266A1 ld (crspos),hl ;Pour ligne suivante
A14C 7D LD A,L
A14D FE1A cp 26 ;25 lignes imprimées?
A14F 20C2 JR NZ.LL1
A151 2A64A1 exit ld hl,(oldpos) ;si oui, restaurer
A154 CD75BB call setcrs ;ancienne position curseur
A157 C9 RET ;et retour
A158 C5 PRTOUT PUSH BC
A159 CD2EBD p1 call tstptr ;printer busy?
A15C 38FB JR C,P1
A15E CD31BD call prtchr ;sortir un caractère
A161 C1 POP BC
A162 C9 RET
A163 00 MODE DEFB 0
A164 0000 OLDPOS DEFW 0000
A166 0000 CRSPOS DEFW 0000


Les commentaires dans le listing devraient rendre le programme facilement compréhensible. La seule particularité est constituée par la méthode de calcul du nombre de caractères à sortir par ligne. C'est pourquoi nous voudrions évoquer cette question brièvement.

Après que nous ayons appelé SCR GET MODE, l'accumulateur contient, suivant le mode, 0, 1 ou 2. En outre les flags carry et zéro ont les états suivants:

Mode 0 = Carry 1, Zéro 0
Mode 1 = Carry 0, Zéro 1
Mode 2 = Carry 0, Zéro 0


L'instruction SLA décale le contenu de l'accumulateur d'un bit vers la gauche. Cela correspond à une multiplication par deux. L'état du flag carry est en outre tranféré dans le bit 0 de l'accumulateur et le bit 7 qui a été 'expulsé' est placé dans le carry.

En mode 0, le 0 qui se trouve dans l'accumulateur subit une rotation. Cela n'a pas d'influence sur le contenu de l'accumulateur. Mais comme le flag carry qui a été mis par SCR GET MODE est transféré dans le bit 0 de l'accumulateur, l'accumulateur contient 1 après cette instruction. Ce 1 a pour effet que une fois 20 caractères seront imprimés par ligne.
En mode 1, l'accumulateur contient un 1, le carry est nul dans ce mode. Après SLA, l'accumulateur contient un 2. Ce sont donc deux fois 20 caractères qui seront sortis par ligne. Le fonctionnement est analogue en mode 2. Le résultat de SLA est un 4 dans l'accumulateur, ce qui entraîne 4 fois 20 caractères par ligne d'impression.

Le principe est quelque peu différent quand il s'agit de produire un hardcopy graphique. Nous ne pouvons pas alors utiliser les routines TXT SET CURSOR et TXT RD CHAR. Tout d'abord, GRA INITIALISE active le mode graphique. Ensuite, avec GRA GET PAPER nous déterminons le numéro de couleur du fond. Tous les points de l'écran seront comparés à cette valeur. Si la couleur d'un pixel est différente de celle du fond, un point sera produit sur le papier.

Malheureusement, le CPC ne dispose que d'une connexion 7 bits avec l'imprimante, il en résulte certaines complications. Cela signifie d'abord Que nous pouvons sortir en une fols sur l'Imprimante 7 points placés les uns sous les autres. Le graphisme du CPC a en tout une résolution graphique verticale de 200 points. Mais divisé par 7- cela ne donne pas une valeur entière, Il y a donc un reste, c'est-à-dire des lignes de pixels qui devront être traitées d'une façon particulière. Le problème est cependant Identique- quel que soit le mode de texte.
La sortie 7 bits pose un autre problème pour la transmission des instructions à l'imprimante, L'activation du graphisme avec ESC L nécessite pour les 640 pixels par ligne une Indication qui ne peut être transmise par le CPC, Pour obtenir le nombre voulu de points graphiques sur l'imprimante, la séquence de commande pour l'imprimante est:

PRINT #8,CHRS(27);"L";CHR$(128);CHR$(2)

Le problème vient de la valeur 128. Exprimé en terme binaire, 128 est un nombre dont le huitième bit (le bit 7) est mis. Tous les autres bits sont nuls. Si nous envoyions cette valeur sur l'imprimante, celle-ci ne recevrait qu'un 0, puisque le huitième bit est utilisé comme strobe et n'est pas sorti vers l'imprimante.

Nous avons contourné ce problème de façon pas très élégante, en ne sortant horizontalement que 639 points. C'est certes un point de moins qu'il n'y en a sur l'écran, mais nous réduisons ainsi la première valeur à transmettre a 127 (maximum).

Avant que nous n'en venions maintenant au listing du hardcopy graphique, il nous faut encore relever une particularité.

Bien que l'écran ne représente physiquement que 200 lignes de grille, toutes les routines graphiques du CPC raisonnent à partir d'une résolution graphique de 400 points. 11 en résulte un meilleur rapport entre les directions X et Y que si l'on ne comptait que les deux lignes véritablement existantes.

La conséquence est facile a observer si vous essayez par exemple le programme de dessin d'un cercle qui vous est proposé dans le manuel du CPC. Vous voyez en effet que le cercle est presque rond. Sans cette correction, c'est une ellipse allongée dans le sens de la largeur qui serait produite.

Cette correction doit également figurer dans notre hardcopy, mais sous une forme exactement contraire. Nous devons également déterminer les coordonnées graphique dans la grille de 400x610 points, mais sur l'imprimante, nous ne sortons oue 200 points vertcicalement, pour ne pas avoir de gaspillages trop importants.

; Hardcopy graphique pour DMP 2000
; et compatibles epson
;
ORG #A000

[INCOMPLET]

100 ' Hardcopy graphique pour DMP 2000
110 ' et compatibles epson
120 ' Le hardcopy doit etre appele par call &AOOO'
130 '
140 DATA CD,BA,BB,CD,E7,BB,32,B8,A0,CD,6C,A0,21,8F,01,22
150 DATA B9,AO,11,00,00,3E,07,32,BB,AO,CD,77,AO,OE,00,3A
160 DATA BB,A0,47,E5,D5,C5,CD,F0,BB,C1,D1,21,B8,A0,BE,E1
170 DATA 37,20,01,A7,CB,11,2B,2B,10,E9,CD,AA,A0,79,CD,A1
180 DATA A0,13,E5,21,7F,02,37,ED,52,E1,38,05,2A,B9,A0,18
190 DATA CC,23,7C,B5,C3,2B,11,00,00,22,B9,A0,3E,07,BD,20
200 DATA B9,7C,B4,20,B5,3E,04,32,BB,A0,18,AE,3E,1B,CD,A1
210 DATA A0,3E,31,0D,A1,A0,C9,E5,3E,42,CD,1E,BB,E1,28,02
220 DATA E1,C9,3E,0D,CD,A1,A0,3E,0A,CD,A1,A0,3E,1B,CD,A1
230 DATA A0,3E,4C,CD,A1,A0,3E,7F,CD,A1,A0,3E,02,CD,A1,A0
240 DATA C9,CD,2E,BD,38,FB,CD,2B,BD,C9,3A,BB,A0,FE,07,C8
250 DATA AF,CB,11,CB,11,CB,11,C9,00,00,00,00
260 '
270 MEMORY 40959
280 s=0
290 FOR i= 40960 TO 41147
300 READ b$:b=VAL("&"+b*):P0KE i,b:s=s+b
310 NEXT
320 IF s<> 23051 THEN PRINT "erreur en DATA"
330 END

★ ANNÉE: ???

Page précédente : La bible du CPC 6128 : 2.02.02 La RAM du système d'exploitation du CPC 6128
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 519 millisecondes et consultée 1142 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.