Le CRTC6845, leçon 1
Lorsque j’ai voulu reprendre le CPC après plusieurs années d’interruption, j’ai été très surprise que constater qu’en 2020 on nous conseillait encore des documents des années 90 comme base pour l’apprentissage de la programmation hardware. La documentation de Gozeur, les vieux Quasar, c’est bien mais c’est daté. Et incomplet. Parfois même erroné. Depuis Longshot a sorti son Compendium, mais l' »Elite » CPCienne clame à qui veut l’entendre que ce document est incompréhensible. C’est assez drôle d’ailleurs, parce que les personnes les plus enthousiastes à propos du Compendium sont des démomakeurs sur PC, qui utilisent des cartes vidéo CGA et EGA. Je ne résiste pas à l’envie de préciser que sur ces cartes c’est un CRTC2 qui est employé, ce qui devrait aussi faire très plaisir à l' »Elite ».
Bref, je pense qu’il serait intéressant de redémarrer une série sur le CRTC, sa vie, son oeuvre. Histoire de (re)partir sur de bonnes bases, n’est-ce pas ?
Si vous lisez les documentations officielles du CRTC, on vous y racontera que ce composant sert à gérer des affichages en mode texte. Mais… Le CPC, un mode texte ? Et oui ! Mais il est bien caché. Du point du vue du CRTC, il ne fait que donner (en plus des signaux de synchronisation, on y reviendra plus tard) une adresse sur 14 bits (c’est à dire qu’il adresse 16Ko de RAM), et un numéro de ligne. De son point de vue, il envoie « Là faut afficher le caractère dont le code est à l’adresse xxx, et on est à la 2e ligne du caractère ». Et le pire, c’est qu’il travaille à la microseconde, ce qui correspond à la largeur de deux octets.
C’est grâce au Gate Array et à la cuisine électronique du CPC que la magie opère : Le GA est cadencé à 16Mhz, à cette vitesse il est capable de gérer un pixel mode 2. Pour déterminer l’adresse mémoire à laquelle récupérer l’octet à afficher, on prend les données issues du CRTC et on fait une bidouille électronique (On parle en binaire bien entendu) :
Vous noterez que le dernier bit de l’adresse mémoire est dépendant d’une horloge : On a dit que le CRTC travaillait à 1MHz, ce qui revient à dire qu’il fournit une adresse toute les microsecondes. Or, on a besoin de deux adresses différentes pour lire les deux octets qu’on doit afficher dans l’intervalle. On a donc un compteur à 2MHz pour ce bit, qui change toutes les demi microsecondes : Lorsque le CRTC change d’adresse (mettons que WMA est à #3000, et que le compteur de lignes est à 0), ce compteur passe à 0 ce qui nous fait une adresse mémoire de #C000. Le Gate Array décode l’octet et l’affiche, ce qui lui prend une demi microseconde. Ensuite le compteur passe de 0 à 1, et l’adresse mémoire devient donc #C001. Le Gate Array a donc l’adresse du second octet à afficher. A la demi microseconde suivante, le CRTC incrémente WMA qui passe à #3001. Le compteur repasse également à zéro et on obtient donc l’adresse #C002 que va lire le Gate Array pour l’affichage, etc.
Le compteur de lignes pourrait gérer des caractères de 32 lignes de haut grâce à ses cinq bits, mais M. Amstrad a décidé que huit lignes étaient bien suffisantes. Ce nombre est paramétrable dans le CPC, mais on est limités à 7 valeurs seulement pour ce compteur : Au delà de 7, les bits sont jetés et c’est comme si on recommençait à compter à partir de zéro. La ligne de texte se répète. Attention, ça n’est pas parce que les bits en question sont inutilisés par le CPC qu’il ne sont pas gérés par le compteur de lignes. Ce dernier est interne au CRTC et les broches du composant sont mises à jour, que le CPC les utilise ou non.
Il en va de même pour les deux bits de WMA qui vont à la poubelle aussi : Ce sont ceux qu’on appelle Overscan bits. Quand ces bits sont à 1 il est possible d’incrémenter les bits 12 et 13 de WMA, ce qui permet d’utiliser deux pages de 16Ko contiguës en RAM. Un exemple ? Considérons que WMA=#23FF (et le compteur de lignes à 0), ce qui nous fait afficher les octets aux adresses #87FE et #87FF. Si on incrémente WMA pour le prochain caractère, on obtient #2400, ce qui nous donnera #8000 et #8001 : WMA à #2400 est équivalent à WMA à #2000 à cause des bits « jetés à la poubelle ».
Par contre, imaginons qu’on aie WMA=#2FFF (équivalent à #23FF, toujours à cause des bits à la poubelle). Ça nous affichera de la même manière les octets en #87FE et #87FF. Mais si on incrémente WMA, on arrive à WMA=#3000, ce qui nous amène à l’adresse #C000 et #C001 et non plus #8000. En clair, les Overscan bits ne sont donc pas une commande cachée du CRTC, mais le simple forçage de la propagation d’une retenue dans WMA.
Un petit listing pour la route ? Trois lignes en Basic :
BORDER 6
OUT &BC00,6:OUT &BD00,30
OUT &BC00,12:OUT &BD00,&3C
Les deux premiers outs disent au CRTC d’afficher 30 lignes de texte au lieu de 25. On dépasse donc les 16Ko de mémoire, mais comme les Overscan bits ne sont pas positionnés, on « boucle » sur la même page et l’image se répète:
La deuxième ligne de outs positionne les Overscan bits, et on peut donc apercevoir une autre page, celle qui démarre en &0000 !
Et voilà, c’est tout pour aujourd’hui ! Un billet entier sur le CRTC sans avoir mentionné une seule fois le mot « registre », c’est un exploit. Ça devrait changer avec le prochain cours.
[…] va essayer de localiser la panne sans regarder la carte mère. Ca tombe bien, le billet précédent concernant le CRTC contient la clef du problème. Que voit-on ? L’image est synchronisée correctement, donc on […]