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 Src's » Pointers - Windows System
» Coding » Comparaison de chargements disquettes (système VS hardware) et conclusion
» Coding » Comparaison d'affichages de caractères (système VS hardware)
» Coding » Read the Tape Data's Whitout the System (The Amstrad User)
» Coding Src's » Systeme Protection pour Newlog4
» Coding » System - Les Routines System (SOS Programmeurs)
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.732-desktop/c
Page créée en 574 millisecondes et consultée 1912 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.