Les articles Amstrad >Les produits Amstrad > Les CPC > Programmation > Assembleur > Affichage de sprite, raster, registres (Plissken)

Affichage de sprite, raster, registres (Plissken)

Bonjour, voici le 2e cour d'assembleur sur CPC destiné aux débutants.
Commençons par des informations sur les registres :
Bon, si cela n'est pas très clair, je peux vous envoyer des infos complémentaires. Il y a plusieurs types de registres, je vais les expliquer.



Les registres 8 bits
-------------------
Ce sont les registres A, B, C, D, E, F, H, L. Ils existent en double. Ils permettent de stocker des valeurs comprises entre 0 et 255 mais A et F sont un peu spéciaux par rapport aux autres.

A : appelé aussi "accumulateur", il reçoit le résultat d'une opération arithmétique ou logique sur 8 bits. Il sert aussi à stocker des données.

F : registre flag. Les bits de ce registres sont modifiés après toute opération logique ou arithmétique. Par exemple, ils peuvent indiquer si un débordement s'est produit dans un registre, ou si le résultat d'une opération est nul. Il sert a prendre des décisions logiques.



Les registres 8 bits spéciaux
-----------------------------
R : refresh. Bon, ce registre sert à rafraîchir la mémoire du cpc, et peut être utilisé comme un générateur de nombres aléatoires

I : registre d'interruption. Utilisé en mode d'interruption im2.



Doubles registre 16 bits.
-------------------------
Le Z80 possède des registres 16 bits, ce qui est plutôt rare pour un microprocesseur 8 bits.

les doubles registres sont la réunion de 2 registres : BC, DE, HL.


Registres d'index 16 bits
-------------------------

IX et IY : servent pour l'adressage indexé. Pas nécessaire de les connaitre à notre niveau. Je ne m'en suis pas encore servi.



Registre 16 bits spéciaux
-------------------------
SP : pointeur de pile
PC : compteur de programme : contient l'adresse de l'instruction devant être actuellement traitée par l'unité centrale.

Voila, je reste disponible pour des infos complémentaire sur les registres, mais vous n'avez pas à connaitre par coeur leur fonctionnement pour les utiliser.



Affichage de sprite avec Ldir et Ldi.
-----------------------------------
Voici quelque chose d'intéressant, l'affichage de sprite, il y a plusieurs méthodes, voici les plus simples : ldir et ldi.

Un sprite, qu'est ce que c'est ?
C'est un bout de mémoire que l'on affiche à l'écran. Dans les jeux comme Barbarian, Megablaster, ou encore Batman the movies (excellents jeux), le bonhomme que vous déplacez est un sprite. En gros, le sprite (ou lutin en français) est un élément de la mémoire pouvant être affiché n'importe où sur l'écran.

Comment fait-on pour l'afficher ?
Souvenez-vous du précédent cours, je vous expliquais comment afficher une image à l'écran.

ld hl, &4000
ld de, &c000
ld bc, &4000
ldir

Et bien nous allons changer un peu cette routine car ici nous n'afficherons pas une image de la taille de l'écran. La mémoire écran est la même dans les 3 modes écran 0, 1, 2, mais l'organisation de cette mémoire n'est pas la même suivant les modes.
Mode 0 : 16 couleurs, 160*200 1 octet de la mémoire=2 pixels de l'écran
Mode 1 : 4 couleurs, 320*200 1 octet de la mémoire=4 pixels de l'écran
Mode 2 : 2 couleurs, 640*200 1 octet de la mémoire=8 pixels de l'écran.

Bon, il n'est pas nécessaire pour l'instant de charger un utilitaire de dessin, nous allons le faire autrement.

Dans notre exemple, on va afficher un sprite en mode 1, de 4 octets de large, donc de 16 pixels et de 16 octets de haut, donc, de 16 lignes de haut.

Org &6000;
ld HL, &4000 ; on met le sprite ici
ld de, &c000 ; il sera afficher a la première ligne de l'écran
ld bc, 4 ; largeur du sprite (ici 4 octets)
ldir
ret

Il ne se passe rien, normal, il n'y a rien en &4000. Nous allons y remèdier. Nous allons mettre la valeur 255 (valeur maximale d'un octet) à partir de &4000 et jusqu'à la fin du sprite : 4*16 octet, donc 64 octets.
for i=0 to 64:poke &4000+i, 255:next. Voila, le sprite est "dessiné".

Nous relançons le programme et une ligne apparait a l'écran. Gagné ! Mais nous voulions afficher 16 lignes en hauteur. La solution simple serait de faire une routine pour chaque ligne :

Org &6000;
ld HL, &4000 ; on met le sprite ici
ld de, &c000
ld bc, 4 ; largeur du sprite (ici 4 octets)
ldir
ld hl, &4000+4 ; on a afficher les 4 1er octects du sprite, donc on se décale de 4 octets.
ld de, &c800 ; 2 ligne écran
ld bc, 4
ldir
. . .
jusqu'a la 16 lignes.

Ca va, on n'a que 16 lignes à afficher, mais on peut faire plus pratique et vous allez apprendre plus de chose qu'avec la routine précédente.

ld hl, &4000
ld de, &c000
ld bc, 16 ; on a 16 lignes à afficher, bc va nous servir de compteur.
affiche push bc : push de ; on met dans la pile le contenu de BC et DE (on les sauvegardes), car il vont être modifiés après, mais on aura besoin de leur valeur originale.


ld bc, 4 ; largeur d'un sprite
ldir ; HL et DE sont deja définis. Mais comme DE est modifié par ldir, il a fallu le sauver avant.


pop de ; on ressort DE la pile ou il était sauvegardé.
ex hl, de ; le contenu de DE va dans HL
call &bc26 ; vecteur système qui calcul l'adresse en dessous de celle actuelle et qui ne marche qu'avec le registre HL
ex hl, de ; on remet la valeur de l'adresse écran calculée dans DE
pop bc ; on ressort BC de la pile
dec b ; on enlève 1 a b
jp nz, affiche ; tant que B différent de 0 on retourne au début de la routine
ret ; on stoppe le programme

Voila le déroulement de la routine : on charge BC avec le nombre de ligne que fait le sprite, on charge de avec l'endroit de la mémoire écran ou doit être affiché le sprite. Hl est charge avec l'adresse où est le sprite en mémoire.
BC et DE sont sauvés car ils vont servir pour autre chose après, BC change d'utilisation et contient la largeur d'un sprite, ldir sert à l'afficher.

ex hl, de ; le contenu de DE (adresse écran) et mis dans HL
call &bc26 ; ce vecteur système sert à calculer l'adresse écran en dessous de celle actuelle.
ex hl, de ; le résultat du calcul étant dans HL, on le met dans DE
pop bc : on sort BC de la pile
dec b ; b=b-1, il était au départ a 16, puis il est mis a 15
jp nz, affiche :tant que b est différent de 0 on retourne au début de la routine, sinon, on va a la suite, ici RET

Si vous n'avez pas compris, dites-le moi : lynxamstrad@hotmail.com .

Vous savez comment afficher un sprite avec Ldir, il nous reste à voir comment on le fait avec ldi.

Dans la routine précédente, vous enlevez ldir et ld bc, 4 et vous mettez autant de ldi que vous voulez afficher d'octets.
Ldi : le contenu de l'octet pointé par Hl est recopié dans l'octet pointé par DE et ces 2 registres sont incrémentés.
Exemple :

ld hl, &4000
ld de, &c000
ldi:ldi:ldi:ldi
ret

est la même chose que

ld hl, &4000
ld de, &c000
ld bc, 4
ldir
ret

Avec Ldi, on gagne un registre (BC), mais on perd en mémoire car on doit mettre autant de ldi qu'il y a d'octets a afficher.

C'est fini pour l'affichage de sprite, voyons un peu les rasters. Ldir prend plus de temps machine que Ldi, mais qu'est-ce que le temps-machine ? le temps machine est une unité de mesure du temps que met le Z80 à effectuer une instruction. On mesure le temps-machine en Nop. Un raster est un changement de couleur dans une encre pendant le balayage écran.
Voyons comment faire pour créer des rasters :
Ce qu'il faut savoir, c'est que le composant du CPC permettant de changer les couleurs est le gate array (voir cours précédent). C'est un composant extérieur au Z80, dont on va devoir utiliser l'instruction : out (c), x.
On peut adresser le Gate array à l'adresse &7f+xx(xx=encre a changer)
00:fond de l'écran
01 a 0f :pen 1 a 15
10 : bord de l'écran.

ld bc, &7f00
out (c), c
ld c, couleur
out (c), c

Avec cette commande, on peut changer le fond de l'écran. En basic on peut faire ink 0, 0 pour mettre le fond de l'écran en noir. Mais les couleur du basic ne correspondent pas aux couleurs du gate array. Donc, voici un tableau de correspondance.

Couleur basic

Couleur gate array

0&54
1&44
2&55
3&5c
4&58
5&5d
6&4c
7&45
8&4d
9&56
10&46
11&57
12&5e
13&40
14&5f
15&4e
16&47
17&5f
18&52
19&42
20&53
21&5a
22&59
23&5b
24&4a
25&43
26&4b



Donc, la couleur 26 du basic est &4b pour le gate array.

testez ce programme :

org &6000
ld bc, &7f10
out (c), c
ld c, &58
out (c), c
ret

Le bord de l'écran se change en violet et se remet dans la couleur de départ. Pourquoi ? Tout simplement parce que le système remet toujours l'encre d'origine.
maintenant tapez :

org &6000
début call &bd19
halt
halt
ld bc, &7f10
out (c), c
ld c, &58
out (c), c
halt
ld c, &54:out (c), c
call &bb1b
jp nc, début
ret

le border de l'écran contient plusieurs couleurs : violet et noire. Comment est-ce possible ? Et bien pendant le balayage écran on change les couleurs du border de l'écran et ainsi on peut mettre plusieurs couleurs dans la même encre. Si vous vous amusez a mettre plusieurs encre dans le border ou une autre encre, vous verrez peut-être des couleurs clignoter. C'est normal et je vais l'expliquer. toute les 6, 5 lignes de balayées, le Z80 va a l'adresse &0038 voir ce qu'il a a effectuer, et comme il ne fait pas toujours la même chose, le moment ou il va changer les couleurs n'est pas le même, ce qui se traduit par un décalage qui produit un clignotement. La solution serait de mettre l'instruction Ret (&c9 en hexadecimal), ainsi, dès que le Z80 ira voir en &38, il repartira aussitot.

 

Seulement, les vecteurs systèmes ne seront plus disponibles car c'est quand le z80 va voir en &38 qu'ils sont pris en compte. Donc, il faut se passer des vecteurs systèmes et cela sera le sujet du prochain cours :rendre les interruption régulieres et remplacer les vecteurs système avec l'explication du test de touche et de VBL.

 


Bon, revenons au temps-machine. Pour avoir une idée du temps-machine que prend un programme, il suffit de changer la couleur du bord de l'écran(c'est plus pratique)avant l'exécution de la routine et après.
exemple :

début call &bd19
halt
halt ;on attend 2*6, 5 lignes pour que le raster soit visible
ld bc, &7f10
out (c), c
ld c, &58 ;violet
out (c), c
ld hl, &4000
ld de, &c000
ld bc, 16
affiche push bc:push de
ld bc, 4
ldir
pop de
ex hl, de
call &bc26
ex hl, de
pop bc
dec b
jp nz, affich
ld bc, &7f10
out (c), c
ld c, &54 ;noir
out (c), c
call &bb1b
jp nc, début
ret

Et regarder le temps que le violet est afficher : plus la routine prend du temps, plus le violet reste longtemps. Et l'optimisation d'un programme sert à diminuer cette bande de couleur, pour avoir plus de temps machine pour faire autre chose. Modifiez cette routine en mettant ldi comme indiqué plus haut dans le cours et observez ce qui se passe : la couleur violet est moins longtemps à l'écran, ce qui signifie que ldi est plus rapide que ldir.



Voila, ce cours est fini, et j'espère qu'il vous conviendra. Si vous n'avez rien compris vous pouvez me contacter de plusieurs manières :
Par mail : lynxamstrad@hotmail.com
Par téléphone : 06-19-11-63-31
Par la poste :

Naslin thomas
14 allée des chenes
49500 SEGRE
FRANCE

 


J'attend vos remarques, suggestions, questions et vous donne rendez-vous dans le prochain cours.

  Voir cet article au format PDF Imprimer cet article

RECHERCHE
LANGUE
* Donathon 2017 *

145 €

 

 

 

 En savoir plus

Le Chat
 Smiles  Loading...
EN LIGNE
8 Personne(s) en ligne (1 Personne(s) connectée(s) sur Les articles Amstrad)

Utilisateur(s): 4
Invité(s): 4

Moonbeam, Golem13, Ast, BDCIRON, Plus ...
Musiques CPC

Lecteur MP3
CPC-Scene Radio

 

 

ROLAND RADIO

Connexion
Identifiant :

Mot de passe :

Se souvenir de moi



Mot de passe perdu ?

Inscrivez-vous !

 

Informations
________________________________

Suivre Amstrad.eu

________________________________

Autres Créations web

________________________________

 

Declaration CNIL : 1005884

Association : 0540200002843

Charte

Avertissements

Plan du site

Carte de France des membres

 

 

 

Facebook.

Twitter.

RSS forum.

RSS News.

Contact.

 

Gaston-Phoebus.com

Amstrad.eu

untour.fr

Cathydeco.com

Higoogle

Harloup.fr

** Faire un don **

 

Conception Phenix © 2000 - 2014