L'interruption vertical blank ou VBI
L'interruption vertical blank (ou VBLANK) gère beaucoup de choses:
- La maj de l'horloge (adresses 18-20),
- la mise en veille (changement de la couleur du moniteur s'il n'y a pas eu de saisie au clavier depuis quelques temps),
- le clavier (répétition d'un caractère par exemple)
- ...
Il y a trois types d'appels de code utilisateur déclenché pendant le VBI:
Immediate Vblank: Le code tourne durant tout le temps où l'affichage est "gelé" car retour du balai à ses origines.
Deferred Vblank: Code lancé à la fin du VBI, puis il fera appel à un autre code qui va remettre en état tous les registres et permettre ainsi de faire repartir le 6502 là où il en était avant l'interruption.
Et enfin les timers: Des compteurs sont décrémentés, le code associé est alors déclenché lorsque les compteurs sont revenus à zéro.
Bien entendu, le code déclenché pendant l'interruption ne doit pas prendre trop de temps (au maximum, l'ensemble des codes doivent consommer le temps pris pour le retour du balai...)
Chacun des trois types d'appels utilise des vecteurs.
Pour modifier les vecteurs Immediate Vblank et Deferred Vblank:
La modification de ces vecteurs s'effectue grâce à la routine située en $E45C (Encore appelé SETVBV).
Elle attend comme paramètres:
Dans l'accumulateur : 6 pour modifier la Immediate Vblank et 7 pour la Deferred Vblank.
Dans le registre X : La partie haute de l'adresse de notre routine
Dans le registre Y : La partie basse de l'adresse de notre routine
Exemple
LDA #$07 ;DEFERRED
LDX VBLANK/256 ;Partie haute
LDY VBLANK&255 ;Partie basse
JSR $E45C
VBLANK
Notre routine...Comme je l'indiquai ci-dessus, le système effectue des tâches pendant cette interruption. Si nous installons notre code, il faut peut-être rendre la main au système afin qu'il effectue toujours ses traitements...
Dans ce cas, notre code devra se terminer, non pas par RTI, mais par un appel au code situé en $E45F (SYSVBV).
Et même si vous ne voulez pas que le système poursuive ses traitements, il ne faut toujours pas terminer par RTI, mais plutôt utiliser le vecteur en $E462(XITVBV), car lors du déclenchement de cette interruption VBI, le système va sauvegarder les registres sur la pile, il faut donc les restaurer à la fin de l'interruption sinon le 6502 et le programme interrompu ne trouverons plus leurs petits et...plantage.
Si l'appel est paramétré sur Deferred Vblank, il faut utiliser le vecteur $E462 (XITVBV) pour sortir.
Exemple de code avec Immediate Vblank:
On va périodiquement éclairer le fond d'écran (pour le graphique 0), puis revenir à la couleur normale:
Exemple de code avec Deferred Vblank:
On va faire défiler toutes les couleurs...
(Pour la gestion des couleurs, voir : le chapitre sur les couleurs)
Exemple très simple de programme pour charger le code en basic:
Il charge le code en mémoire puis l'exécute.
Pour essayer le deuxième programme, il faut faire un reset avant de le charger en mémoire et de l'exécuter.
Pour assembler les deux fichiers, voir l'assembleur.
TASM -65 -b vbiXXX.asm vbiXXX.bin
Ou XXX = def ou imm
Remarque:
546, 547 Vecteur sur la routine initiale de Immediate Vblank
548, 549 Vecteur sur la deferred procedure.
Il est possible de mettre notre code directement en passant par ce vecteur, mais c'est peut-être moins "propre"...
L'adresse 54286 ($D40E): Le bit 6 si positionné à 1 va permettre aux routines du VBI de tourner, à 0, elles vont donc s'arrêter. Essayez donc un POKE 54286,PEEK(54286)-64 pour désactiver le VBI, la répétition des touches ne fonctionnera alors plus...
Cette adresse
servira aussi pour les interruptions DLI. Donc ne modifier
que le bit 6 !
Les timers:
Il existe 5 timers, la plupart étant utilisées par le système, il vaut mieux éviter de jouer avec...
L'intérêt du timer: avoir un code qui se déclenche automatiquement dès que le compteur associé arrive à zéro, donc au bout d'un certain laps de temps, qui est programmable.
Ce timer peut donc fort bien être utilisé pour jouer de la musique: Pas de ralentissement anormal de la musique, ce qui peut se produire hors interrruption lorsque le 6502 effectue des traitements "lourds" et n'est pas disponible pour jouer la musique. Voilà un bon métronome.
Donc il y a 5 timers, mais le timer 2 est le moins dangereux, car laissé à disposition de l'utilisateur (c'est à dire: nous).
Il faut tout d'abord indiquer dans le vecteur l'adresse de notre procédure "timer" (Vecteur 552-553).
Le timer 2 va utiliser le compteur aux adresses 538 et 539.
Pour déclencher le timer, on utilise là aussi SETVBV (routine en $E45C), mais en passant dans l'accumulateur la valeur 2 (timer 2). Dans X, la partie haute du compteur, dans Y, la partie basse.
Un traitement timer est déclenché une seule fois, il faudra éventuellement refaire appel à SETVBV si vous voulez qu'il se réexécute.
Petit exemple, changement de la couleur de fond dès que le temps est écoulé:
les timers ne
peuvent pas se déclencher si le VBI est désactivé. C'est
en effet lui qui gère l'exécution des timers.
C'est tout pour la VBI.