Revenir au plan du site
Changer le mode graphique
Le réglage de la résolution de sortie se fait via le RMR (Registre de Mapping ROM), vous pourrez jeter un oeil à l'annexe hardware pour plus de détail sur ce registre. Sachez pour le moment que comme son nom l'indique, ce registre permet d'activer ou désactiver les connexions de ROM inférieure et supérieure, autant dire qu'il faut le manier avec précaution!
L'intérêt de ne pas faire de la programmation système est qu'on ne va pas se poser de question et surtout ne jamais les activer. La valeur par défaut de notre RMR est %10001100 (ou #8C) et je vous encourage à toujours l'écrire en binaire car il arrivera peut-être un jour où vous connecterez vos propres ROM ;)
À cette valeur %10001100 il suffit d'ajouter le numéro de mode souhaité qui se casera dans les deux bits du bas : 00 pour le mode 0, 01 pour le mode 1 et 10 pour le mode 2.
Ai-je oublié quelque chose? Oui! Il faut envoyer cette valeur sur le port #7F00.
ld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0
ld bc,#7F00+%10001100+%01 : out (c),c ; MODE 1
ld bc,#7F00+%10001100+%10 : out (c),c ; MODE 2
|
Bon,c'est bien mignon d'afficher des points, mais tous ces calculs là, sont-ils bien utiles? Plutôt que calculer à chaque fois le modulo, la division (même optimisée), ne serait-il pas possible de faire un tableau de 200 cases qui contienne nos 200 adresses écran déjà calculées?
La réponse est oui! Nous allons générer directement cette table dans l'assembleur.
adresse_ecran=#C000
largeur_ecran=80
tableau
repeat 25 ; notre écran est composé de 25 lignes
repeat 8 ; de blocs de 8 lignes
defw adresse_ecran
adresse_ecran+=#800
rend
adresse_ecran+=largeur_ecran
adresse_ecran-=#4000
rend
; exemple de lecture de ce tableau de 400 octets
; HL=ligne écran
ld bc,tableau
add hl,hl ; adresses 16 bits, il faut indexer de 2 en 2
add hl,bc
ld a,(hl) : inc hl ; on récupère d'abord le poids faible, le Z80 est little endian
ld h,(hl) : ld l,a ; ensuite le poids fort
; HL=adresse de la ligne
|
Notre programme se trouve considérablement raccourci et plus rapide (mais il occupera un peu plus de mémoire à cause de la table.
BUILDSNA : BANKSET 0
ORG #100
RUN #100
debut
ld bc,160 : ld hl,100 ; en plein milieu de l'écran
call CalculeAdressePixel
ld (hl),c ; écrire le pixel
jr $ ; boucle infinie
CalculeAdressePixel
; BC=coordonnée X (0-319)
; HL=coordonnée Y (0-199)
ld de,tableau
add hl,hl ; adresses 16 bits, il faut indexer de 2 en 2
add hl,de
ld a,(hl) : inc hl
ld h,(hl) : ld l,a
; HL=adresse de la ligne
ld a,c ; on sauvegarde le X avant de diviser par 4
srl bc : srl bc ; diviser le X par 4 pour avoir l'octet en mode 1
add hl,bc
ld c,%10000000 ; encre 1 pour le pixel mode 1 le plus à gauche dans l'octet
and 3 ; avec le modulo 4 on va savoir quel est le pixel en partant de la gauche
jr z,.noShift
.Shift
srl c
dec a
jr nz,.Shift
.noShift
ret ; HL=adresse écran aux coordonnées X/Y données et C est le pixel d'encre 1
;-------------------
adresse_ecran=#C000
largeur_ecran=80
tableau
repeat 25
repeat 8
defw adresse_ecran
adresse_ecran+=#800
rend
adresse_ecran+=largeur_ecran
adresse_ecran-=#4000
rend
|