ASMtrad CPC

Apprenez l'assembleur Z80

Splitscreen ou Rupture d'écran sur Amstrad CPC

Comme nous avons pu le voir, le CRTC sur Amstrad CPC permet de changer l'adresse de début d'écran (appelée offset).
Cependant, si vous faites des tests, ce changement d'écran n'est possible qu'une fois par frame.
Il serait pourtant intéressant de pouvoir changer cet offset plusieurs fois dans la même frame, ce qui permettrait d'avoir par exemple une zone avec un offset puis d'autres avec d'autres offset.
L'intérêt ? Imaginez une première zone scrollant verticalement, puis une autre statique alors que la suivante scrollerait horizontalement.
Tout ce que vous avez pu voir dans des démos sur Amstrad CPC dans les années 90 vient de cette technique.
La rupture d'écran, appelée plus simplement "rupture" ou "splitscreen" vous permettra de changer l'offset plusieurs fois par frame, voire plusieurs fois par ligne.

Principe

La rupture permet donc de changer l'offset d'une partie de l'écran (que j'appellerai rupture). Pour cela nous utilisons les registres 12 et 13 du CRTC.
Mais il existe d'autres registres dans ce même CRTC et c'est justement ce qui va nous être utile.
Comme nous allons y aller progressivement, je n'entrerai pas forcément dans les détails dès le début et n'aborderai pas les incompatibilités CRTC.
Sachez tout de même que nos bons vieux CPC/CPC+ ont au court de leur histoire eu différents CRTC et que ceux-ci ne réagissent pas exactement de la même manière.
Tant que vous ferez des choses simples, il n'y a pas de raison que vos ruptures ne fonctionnent pas sur les autres CRTC.
Cependant, dès que vous ferez de la rupture ligne à ligne ou utiliserez des techniques de ruptures verticales alors il vous faudra penser à faire des adaptations.

Nous souhaitons donc changer l'offset plusieurs fois par écran. Pour cela il faut savoir uniquement une chose: L'offset est pris en compte au bouclage de C4.
C4 ??? Qu'est-ce que c'est que ce truc ?
C4 c'est le compteur interne du registre R4. Retenez bien ce principe.

C4 s'incrémente à chaque ligne de caractère (en standard 8 lignes pixel) jusqu'à atteindre la valeur de R4.
Puis il repasse à 0.
C'est à ce moment qu'il prend en compte l'offset. (Sur crtc 1 et seulement sur celui-ci, il le prendra en compte tant que C4=0, donc attention c'est long: 8 lignes).
Ainsi, si on parvient à faire boucler plusieurs fois C4 à 0 par frame, on pourra changer l'offset autant de fois.

Rupture simple

Comme nous l'avons dit, C4 s'incrémente jusqu'à atteindre R4 puis boucle.
Pour avoir plusieurs bouclages de C4, il suffira donc de changer R4 après chaque bouclage.
Notez que si vos ruptures font la même hauteur, il ne sera utile de redonner les valeurs de R4.
Il faudra cependant retenir une règle en rupture simple (sans changement du nombre de lignes par caractère, donc avec R9 qui est donc égal à 7):
LA SOMME DES VALEURS DES REGISTRES 4 AUGMENTÉES DE 1(pour compter le 0) DOIT ÊTRE ÉGALE Á 39.
Pourquoi ? Parce que 39*8=312 lignes !!!
Pour que votre écran reste à 50Hz, vous devez impérativement avoir ces 312 lignes.

Vous pouvez donc par exemple faire 3 ruptures avec les valeurs R4 suivantes:
14,11,11 car (14+1)+(11+1)+(11+1)=39

Comment faire ces ruptures ?
Imaginons (ce n'est pas le meilleur choix) que notre écran commence en même temps que le signal VBL.
En haut de l'écran, C4 sera donc égal à 0.
Notre C4 va ensuite s'incrémenter à chaque ligne-caractère (donc toutes les 8 lignes pixel).
Donnons-lui donc directement un R4=14 AVANT que C4 n'atteint cette valeur (je vous explique pourquoi après le schémas).

rupture 1

Notre R4 est donc une valeur de seuil. C4 à chaque incrémentation va donc être comparé à R4 pour savoir s'il a atteint son maximum et doit boucler.
Imaginons que C4 ait déjà dépassé 14. Par exemple C4=16 au moment où nous lui donnons la valeur 14...
C4 continuera de s'incrémenter: 17,18,19,20... 127 puis bouclera (R4 est sur 7 bits) à 0 jusqu'à atteindre votre valeur 14...
Vous aurez donc, nous pouvons le dire, beaucoup de lignes de caractères en trop.

Ce bug évoqué, revenons à nos compteurs.

Notre C4 boucle donc quand il atteindra 14. Il repassera à 0 et l'offset sera pris en compte.
Cela signifie qu'on pourra modifier l'offset tant que C4 n'aura pas atteint 14 et que cet offset sera pris en compte pour la rupture suivante.
Je le redis: Pour une compatibilité avec le CRTC 1, il ne faut pas modifier l'offset lorsque C4=0 (première ligne-caractère d'une rupture)

Continuons donc avec notre deuxième rupture.
Nous devons attendre que C4 ait bouclé à 0. Puis nous pourrons redonner notre nouveau R4=11
Bien entendu nous devrons donner R4=11 AVANT que C4 n'ait dépassé cette valeur une nouvelle fois.
Nous pourrons répéter l'opération pour la rupture suivante et c'est même plus fort: nous n'aurons pas besoin de remodifier R4 puisqu'il est déjà égal à 11...

Cependant n'oubliez pas qu'il faudra redonner le R4 de la première rupture au bon moment.
N'oubliez jamais que quoi vous ferez, C4 continuera de s'incrémenter.

Voici donc ce à quoi pourrait ressembler vos ruptures:

rupture 1

R7

Nous savons donc désormais faire des ruptures. Mais il nous manque un élément essentiel: Notre VBL

J'ai effectivement mis une VBL sur notre schéma, mais concrètement n'espérez pas faire fonctionner vos ruptures directement de la sorte.
Il nous faut un signal VBL et il nous le faut une seule fois toutes les 312 lignes.
Pour cela, rien de plus simple, R7 est là pour nous aider !!!

R7 est comparé à C4. Quand C4 atteint R7 alors la VBL est envoyée.
Dans notre cas, nous voulons une seule VBL et on ne peut pas dire qu'elle soit placée au meilleur endroit puisqu'elle se trouve sur un C4=0.
Hors un C4=0 nous en aurons 3. Si nous mettons un R7=0 alors nous aurons 3 VBL à la suite. Votre moniteur ne va pas apprécier et moi non plus.

Il nous faut donc en plus gérer ce registre 7. Ce n'est pas bien compliqué rassurez-vous puisqu'il suffira d'empêcher la condition C4=R7 pour qu'il n'y ait pas de VBL.
Pour cela rien de plus simple puisqu'il suffira de mettre R7 à une valeur que C4 n'atteint jamais pendant tout l'écran et de donner la valeur correcte au dernier.
Si par exemple vous donnez au début R7=30, C4 ne l'atteindra jamais. Lors de la dernière rupture vous pourrez le mettre à 0 une fois que C4 aura dépassé cette valeur.

Je vous disais que faire coïncider le début de l'affichage du moniteur avec le début d'un écran CRTC n'est pas une bonne idée.
En effet, cela ne sert pas à grand-chose sinon à vous embêter.
Entre le signal VBL qui sert au moniteur à se caler et la première ligne que vous voyez à l'écran il se passe pas mal de temps.
Vous ne verrez en fait pas les 4 premières lignes de caractères qui sont cachés sous le plastique du moniteur.
Réellement vous ne verrez que environ 272 lignes, soit 34 lignes de caractères (bien qu'un écran de CPC+ bien chaud vous laissera en voir presque 280).

Une meilleure idée est de dessiner ce que vous voulez voir sur papier pour ensuite faire vos ruptures d'une façon plus logique.

Rupture 3

L'idée est la suivante: que la dernière rupture soit aussi la première.
Je m'explique:
Comme notre VBL permet à notre moniteur de se caller, il suffit de l'envoyer au bon moment pour obtenir ce qu'on veut.
Mais comme ce signal n'est qu'un signal de synchro, on peut l'envoyer un peu n'importe quand (bon je simplifie ne l'oubliez pas).
Aussi rien ne nous empêche de l'envoyer au milieu d'une rupture.

Pour essayer de vous faire comprendre l'idée, voici un autre schéma:

rupture 4

Attardez-vous sur la zone en vert.
Comme vous pouvez le voir, celle-ci comprend le logo du bas, mais ne s'arrête pas immédiatement à la fin de celui-ci.
La rupture qui contient le logo occupe 10 lignes caractères, et C4 va rencontrer R7 en ligne 7.
Ainsi le moniteur va se caler sur la VBL et notre rupture continuera jusqu'à R4 qu'on aura bien entendu mis à 10.
La VBL se produira alors au milieu de cette rupture.

La structure de notre écran sera donc la suivante:
Nous commencerons par la rupture rose pour simplifier les choses.
-On attend d'avoir dépassé le bouclage de C4 puis R4=5, R7=18 (à aucun moment C4 n'atteint 18, nous n'aurons donc jamais de VBL). R12 et R13 pour l'écran suivant sont donnés.
-On attend d'avoir dépassé le bouclage de C4 (attendez au moins la ligne de caractère 1 pour éviter des ennuis sur CRTC 1), puis: R4=16 et on donne l'offset de la rupture suivante.
-On attend d'avoir dépassé le bouclage de C4. R4=4 et offset de la rupture suivante.
-On attend d'avoir dépassé le bouclage de C4. R4=10, R7=7 pour avoir une VBL au bon endroit et on donne l'offset de la rupture suivante: le rose.
-On boucle

En résumé

En résumé, faire des ruptures est quelque chose de facile.
Une fois qu'on a compris qu'il suffit d'attendre que C4 ait bouclé pour le modifier à nouveau, tout est compris.
Ne reste alors plus qu'à penser au signal de synchronisation qui doit être unique

Petite remarque sur le border. Celui-ci n'est pas obligatoire mais c'est toujours mieux d'en mettre.
Le registre concerné est R6. Quand C4=R6 alors du border est envoyé. Jusqu'au bouclage de C4.

Les autres ruptures

La première évolution de la rupture simple possible est la Ligne à Ligne (LaL).
Là encore c'est assez simple puisqu'il suffit de s'occuper de R9.
R9 donne le nombre de lignes dans une ligne-caractère.
En standard R9=7 et vous avez 8 lignes par caractère (0 à 7).
En passant R9 à 0 vous aurez donc des caractères de 1 ligne seulement.
Cependant cela ne suffit pas puisque comme nous l'avons dit, l'offset n'est pris en compte qu'au bouclage de C4.
Si R4>0 alors vous ne pourrez pas changer d'offset à toutes les lignes.
La solution est bien évidement toute trouvée en mettant donc R4=0 et R9=0.
Il vous faudra cependant bien faire attention à ne pas mettre trop de lignes ou pas assez pour bien avoir 312 lignes par frame.

Parlons un peu des ruptures verticales.
Les techniques de ruptures verticales consistent à diviser une ligne en plusieurs blocs horizontaux.
Comme pour la rupture simple, on a des équivalents horizontaux au niveau des registres.
R0 (et son compteur C0) détermine la largeur en word d'une ligne, tandis que R2 détermine la position de la HBL(signal de synchro horizontal).
De même le border est géré par R1.
Vous devez respecter la règle de 64Nops par ligne (et donc entre deux signaux HBL)

D'autres techniques existent et sont des évolutions de la rupture verticale.
Pour la RVMB, RVI ou RVLL, je ne vais pas entrer dans le détail dans cet article, nous y reviendrons un jour prochain.
Sachez simplement que comme en rupture verticale on doit utiliser un R4=0, nous ne sommes pas obligé d'avoir un R9=0...
En effet, si R9>0, le compteur C9 s'incrémentera à chaque ligne (R0). Vous pourrez donc obtenir la ligne suivante du caractère.
C'est assez compliqué à expliquer sans schéma et comme déjà dit ce n'est pas le sujet de cet article.

Conclusion

Avec cet article vous devriez normalement savoir faire des ruptures classiques. La suite sera donc de voir comment faire des scrollings hard.
Nous parlerons dans un premier temps du scrolling horizontal, puis du scrolling vertical.

En espérant vous voir les utiliser dans vos jeux.

Je tiens à remercier CheshireCat et Longshot pour la relecture de cet article ainsi que les corrections suggérées.

X

CONNEXION




Inscription