CODING ★ LES VECTEURS SYSTEME DES CPC: EXEMPLE D'USAGE DES ROUTINES GRAPHIQUES ★

System - les Routines System - Exemple d'Usage des Routines Graphiques (SOS Programmeurs)

Le listing qui suit est assez complexe , si vous êtes vraiment débutant , il rique de vous plonger dans un abîme de perplexité ce qui est normal . Vous pouvez vous contenter d'étudier l'appel des routines système et ignorer le reste . Sinon , une étude approfondie vous permettra d'éclaircir le mystère des boucles , de la gestion des pointeurs , et constitue une bonne pratique des connaissances dévoilées dans les cours d'assembleur de SOS5 et SOS6 .

Les effets de ce programme sont des plus spectaculaires pour un faible encombrement en RAM (un peu moins de 350 octets) , les spécialistes et les débutants acharnés pourront vérifier qu'il suffit de modifier quelques octets pour obtenir des dizaines d'effets différents . Quelques suggestions à ce sujet seront faites à la fin du chapitre . Dans sa version actuelle le programme accomplit 2 actions essentielles :

1A : Tracé d'un carré au centre de l'écran entouré par 18 carrés concentriques à chaque fois d'une couleur différente .
1B : Retraçage des mêmes carrés en affichage XOR qui efface la série de carrés depuis l'intérieur et répétition du tout 21 fois .

2 : La série de carrés précédente est retracée 21 fois de l'extérieur vers l'intérieur , toujours en XOR mais avec un décalage des couleurs qui provoque un effet du genre 'hyper-espace' .

----------------
— FONCTIONNEMENT -
----------------

Les 1ères lignes du programme ne sont qu'une simple mise en œuvre des routines système pour initialiser le programme puis cele devient rapidement incompréhensible malgré les abondants commentaires . Ne paniquez pas , et avant d'aborder le listing lisez ce qui suit .

Il est question d'afficher un carré , de le répéter en augmentant sa taille à chaque fois (21 fois de suite) , puis de recommencer dans le sens inverse c'est à dire en retraçant tout l'ensemble du plus grand carré vers le plus petit et toujours 21 fois .

Attaquons point par point .

Pour pouvoir agrandir ou diminuer une figure , il est préférable de la tracer par rapport à son centre afin de disposer ce coordonnées négatives et positives par rapport à ce centre . Ceci est valable dans n'importe quel langage de programmation et pour cela l'origine est mise en 320,200 qui est le centre de l'écran .

1 Il faut une routine capable d'agrandir le carré c'est AUGCARRE .
2 Une seconde pour le diminuer , ce sera DIMCARRE .

Ensuite il faut une boucle de répétition pour agrandir le carré tout en l'affichant puis une autre semblable pour le diminuer . On constate que l'une ou l'autre de ces opérations demande EXACTEMENT les mêmes instructions , seule la routine de calcul du prochain carré sera (AUGCARRE ou DIMCARRE) selon de cas . Il serait particulièrement stupide d'écrire 2 fois la même boucle pour une différence si mineure ! Contrairement au BASIC , un programme assembleur peut se modifier lui même au cours de son déroulement . Par exemple :

LD HL,AUGCARRE ;Adresse de la routine à activer dans HL (ou autre rr) .
LD (ROUTINE+1),HL ;Insérer l'adresse de la routine à activer à l'adresse
ROUTINE+1 . Le '+1' est vital car dans cet exemple , l'assembleur donne au
label ROUTINE la valeur de l'adresse ou figure l'octet #CD qui veut dire CALL
et c'est l'OCTET SUIVANT qui contient l'adresse de la routine à activer .
;Ex : #CD #40 #9C = CALL 40000 (MSB , LSB inversés) .
;
Début de boucle et routine
;
ROUTINE CALL AUGCARRE
On pourrait aussi écrire :
LD HL,AUGCARRE
LD (ROUTINE),HL
;
Début de boucle et routine
;
DB #CD CALL défini comme octet .
ROUTINE DW 0 ;2 Octets vides pour loger la routine à appeler .

Dans ce cas , le '+1' n'est pas nécéssaire les 3 octets de l'instruction étant divisés en 2 par DB et DW . Du point de vue de l'assembleur , c'est stictement identique au 1er exemple , faites comme il vous plait mais ne vous trompez pas sinon tout plante ! A part ça , le nombre d'auto modifications dans un programme n'est limité que par votre résistance nerveuse à ce genre d'exercice .

Ce n'est pas tout ! Pour tracer un carré ou toute autre figure , il faut en connaître les coordonnées . PARACAR contient le point x,y du 1er sommet du carré (pour MOVE) suivi des 4 point x,y (pour 4 DRAW) chaque point demandant 2 octets (Valeur 16 bits) .

Le programme est succeptible d'être appelé à plusieurs reprises , la table PARACAR ne doit donc subir aucune modification , elle doit donc être reproduite dans une seconde qui contiendra les nouvelles coordonnées fournies par les routines de calcul . La double opération agrandissement/réduction complique tout ! Pour la seconde opération il faudra partir du plus grand vers le plus petit , donc utiliser une troisième table pour effectuer un transfert provisoire . Soit :

Table à préserver : PARACAR (20 octets coordonnées figure du carré)
Table de transfert : PARACAR1 (20 octets quelconques)
Table de calcul et tracé : PARACAR2 (20 octets quelconques)

-----------------------------------
- ALGORYTHME DE GESTION DES 3 TABLES -
-----------------------------------

ENTREE DU PROGRAMME : Copie des paramètre d'origine dans table transfert , PARACAR va dans PARACAR1

+>DEBUT BOUCLE1 : Recopie de la table de transfert PARACAR1 vers PARACAR2 , à
! chaque tour ceci réinitialise les coordonnées du 1er carré à chaque tour
!
! +->DEBUT BOUCLE2 : On trace 19 carrés .
! !
! ! CORPS DE BOUCLE : PARACAR2 est modifiée à chaque tour et contient en
! ! sortie de boucle les coordonnées du prochain carré à tracer .
! !
! +-! carré à tracer .
!
+ Rectifier la position du carré pour retomber sur les coordonnées du dernier tracé par DIMCARRE (Le plus grand) , implanter DIMCARRE dans le corps de boucle et recopier PARACAR2 dans PARACAR1 .

Lors du second passage par ce point , FLAG ordonera l'arrêt du programme.

-------------------------

Cette gestion d'un programme par tables multiples est essentielle à toute (bonne) programmation graphique . Vous retrouverez toujours des systèmes similaires dans nos cours de graphisme et parfois pire ! Un jeu d'arcade de 40K assembleur se compose généralement de 20-25K de datas images et sprites et 10-15K pour les buffers temporaires . Le programme proprement dit occupe ce qui reste ...

------------------------

;
;- Demonstration routines graphiques -
;
ORG 40000
nolist
;
CALL #BC11 ;Determiner mode en cours
LD (OLDMODE),A ;Et stocker
;
CALL #BB99 ;Idem pour PAPER
LD (OLDPAPER),A
;
CALL #BB93 ;Et pour PEN
LD (OLDPEN),A
;
LD A,1 ;Parametre mode écran
CALL #BC0E ;Fixer Mode 1
;
LD DE,320 ;Placer l'origine au centre de l'ecran
LD HL,200
CALL #BBC9
;
LD A,1 ;Mode d'affichage graphique en XOR
CALL #BC59 ;N'a pas d'influence sur le texte
;
XOR A ;Mettre a 0 le flag interne utilise par le programme
LD (FLAG),A
;
LD HL,AUGCARRE ;Initialiser l'adresse CALL du label ROUTINE
LD (ROUTINE+1),HL ;Voir explications detailles dans le texte
;
LD HL,PARACAR ;Recopier les parametres d'origine du carre dans
LD DE,PARACAR1 ;la table des parametres d'agrandissement .
LD BC,20 ;5 Coordonnees x et 5 coordonnees y 16 bits
LDIR ;Copier
;
RECOM LD B,21
NXTOPER PUSH BC ;Preserver le nombre d'operations
LD HL,PARACAR1 ;Copier encore les parametres , c'est necesaire pour
LD DE,PARACAR2 ;Conserver une trace des donnees pour le second tour
LD BC,20 ;5 Coordonnees x et 5 coordonnees y 16 bits
LDIR
;
LD B,19 ;Nombre de carres successifs
;
BCLCAR1 PUSH BC ;Preserver nombre de carres a dessiner
LD A,(COLODRAW) ;Stylo pour trace
PUSH AF ;Preserver
CALL #BBDE ;Activer GPEN A
POP AF ;Recuperer stylo
INC A ;Stylo suivant
CP 4 ;Mais pas plus de 3 en mode 1
JR C,PASTROP ;Si < 3 on stocke pour le prochain tour
LD A,1 ;Si on depasse 3 on revient a 1
PASTROP LD (COLODRAW),A ;Et on stocke
;
LD IX,PARACAR2 ;DATAS du carre
LD E,(IX+0) ;Initialiser x
LD D,(IX+1)
LD L,(IX+2) ;Puis y . Se souvenir qu'en adressage indirect
LD H,(IX+3) ;MSB et LSB sont inverses . (SOS 5)
CALL #BBC0 ;MOVE
;
LD B,4 ;4 traces a faire pour un carre
UNCARRE INC IX ;Pointer 4 octets plus loin dans la table
INC IX ;puis qu'on charge a chaque tour 2 * 16 bits
INC IX
INC IX
LD E,(IX+0) ;x pour DRAW
LD D,(IX+1)
LD L,(IX+2) ;y pour DRAW
LD H,(IX+3)
PUSH BC ;DRAW modifie les registres ! Presever compteur
CALL #BBF6 ;DRAW
POP BC ;Recuperer compteur
DJNZ UNCARRE ;Continuer le carre
;
ROUTINE CALL AUGCARRE ;Calculer le carre suivant , l'adresse du CALL change
; ;au prochain tour en RECOM
POP BC ;Recuperer le nombre de carres a tracer
DJNZ BCLCAR1 ;Et continuer tant qu'il reste des carres a tracer
;
LD A,1 ;Remettre la couleur graphique a 1 comme au debut
LD (COLODRAW),A
POP BC ;Et recommencer 21 fois .
DJNZ NXTOPER
;
LD A,(FLAG) ;Ici on vient de repeter 21 fois l'affichage
OR A ;Le FLAG nous dit si il s'agit du 1er ou du second
JR NZ,QUITTER ;tour . Si c'est le second on quitte
INC A ;Si non on modifie le flag
LD (FLAG),A ;on le range
INC A ;on change la couleur
LD (COLODRAW),A
;
CALL DIMCARRE ;On diminue le carre (sans l'afficher) car AUGCARRE
; ;etant en sortie de boucle,le carre est aggrandi une
; ;fois de trop pour etre repris au bon endroit
LD HL,DIMCARRE ;On change le programme pour lui faire diminuer
LD (ROUTINE+1),HL ;le carre au lieu de l'augmenter .
LD HL,PARACAR2 ;Ici PARACAR2 contient les dimensions maximales
LD DE,PARACAR1 ;que l'on recopie dans la table de transfert
LD BC,20
LDIR
JP RECOM ;Et on effectue le second tour
;
CALL #BB06
;
QUITTER LD A,(OLDMODE) ;Restaurer le mode écran sauve en entree
CALL #BC0E
LD A,(OLDPAPER) ;Idem pour PAPER
CALL #BB96
LD A,(OLDPEN) ;Idem pour PEN
CALL #BB90
XOR A ;Restaurer le mode graphique normal
JP #BC59 ;C'est fini .
;
AUGCARRE LD IX,PARACAR2 ;Debut de la zone DATA a modifier
PUSH BC
LD B,10 ;10 * 16 bits
NEXTAUG LD L,(IX+0) ;Valeur x ou y dans HL
LD H,(IX+1)
LD DE,-10
;BIT 7,H ;Tester si negatif
JR NZ,NEGAT ;Si oui on liasse DE a -10
LD DE,10 ;Si non on passe en positif
NEGAT ADD HL,DE ;Et on additionne DE a x ou y
LD (IX+0),L ;Avant de le ranger a nouveau dans la table
LD (IX+1),H ;qui sera utilisee comme coordonnees du carre
INC IX ;dans la boucle de trace
INC IX
DJNZ NEXTAUG
POP BC
RET
;
DIMCARRE LD IX,PARACAR2 ;Exactement comme AUGCARRE , il suffit d'inverser
PUSH BC ;DE negatif DE positif pour obtenir une reduction
LD B,10 ;du carre .
NEXTDIM LD L,(IX+0)
LD H,(IX+1)
LD DE,10
;BIT 7,H
JR NZ,NEGAT1
LD DE,-10
NEGAT1 ADD HL,DE
LD (IX+0),L
LD (IX+1),H
INC IX
INC IX
DJNZ NEXTDIM
POP BC
RET
;
OLDMODE DB 0
OLDPAPER DB 0
OLDPEN DB 0
FLAG DB 0
;
COLODRAW DB 1
PARACAR2 DW 00,00,00,00,00,00,00,00,00,00 ;Paramètres du carré en cours.
PARACAR1 DW 00,00,00,00,00,00,00,00,00,00 ;Paramètres 1er carré tracé .
PARACAR DW -10,10,10,10,10,-10,-10,-10,-10,10 ;Paramètres initiaux carré .
;

--------------------------

Si vous voulez vous amuser à modifier ce programme (Mais non il ne faut pas être maso ...)

Le plus simple : Changez les valeurs de PARACAR pour obtenir une figure autre qu'un carré .
Changez la valeur du compteur B (LD B,4) avant la routine UNCARRE , le nombre et la valeur des datas pour créer d'autres figures . ATTENTION , il faut allonger PARACAR2 et PARACAR1 dans les mêmes proportions que PARACAR . Les valeurs de BC dans les 3 routines LDIR doivent être augmentées de 4 pour chaque côté supplémentaires .
Le nombre de carrés (LD B,19) successifs peut être augmenté sous réserve de diminuer LD DE,10 , LD DE,-10 pour resserrer les carrés .
Vous pouvez passer en mode 0 et pousser à 16 couleurs (CP 4 dans BCLCAR1 devient CP 15) .
Changer l'enchaînement des couleurs pour obtenir des effets différents .

Si vous désirez aller plus loin , sachez qu'hors de certaines limites , il est plus simple de réécrire complètement un programme plutôt que
s'acharner à modifier un listing donné .

----------------------------

Dans ce genre de programme , les causes de disfonctionnement et plantages les plus fréquentes sont :

PUSH et POP . Il manque l'un ou l'autre . L'un des 2 (Voire les 2) est (sont) mal placés . PLANTAGE COMPLET .
MSB est inversé avec LSB lors d'un LD r,(IX+d) ou la valeur de display de IX est incorrecte . FIGURE INNATENDUE .
Routine LDIR incorrecte (Mauvaise adresse ou mauvais compteur) . FIGURE INCORRECTE ou PLANTAGE .
Je vous laisse le soin de découvrir les autres , consolez vous en pensant que malgré 3 ans d'expérience , cette simple (hum ?) routine m'a fait l'offense de 11 plantages avant de fonctionner .

» SOURCE
SOS PROGRAMMEURS

★ ANNÉE: ???
★ AUTEUR: MICHEL MAIGROT

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Read the Tape Data's Whitout the System (The Amstrad User)
» Coding » Menu - Soft - Vecteurs System
» Coding » The Adventure Writing System
» Coding » Clefs2 09 - Logiciel Interne Table Var Systeme
» Coding » System - Les Routines System (SOS Programmeurs)
» Coding Src's » Systeme Protection pour Newlog4
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
Page créée en 713 millisecondes et consultée 1429 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.