HD63B45P
7 mai 2024

Un CRTC6345 sur Amstrad CPC

Par Claire CheshireCat

Récemment on m’a parlé d’un CRTC qui serait l’évolution du CRTC6845, compatible pin à pin (Comprendre, qu’on peut mettre à la place d’un 6845 sans aucun problème). J’avais déjà entendu parler de composants de ce genre, mais les références que j’avais trouvées n’étaient pas disponibles à l’achat. Quand j’ai trouvé des HD63B45P, je n’ai pas hésité une seconde !

Tout d’abord, pourquoi remplacer son CRTC originel par celui-ci ? Au rayon des mauvaises nouvelles, si pour une utilisation de tous les jours en Basic ou pour les jeux on n’aura aucun soucis, il est évident que pour passer des démos on notera quelques incompatibilités. Restent les bonnes, voire très bonnes nouvelles : Avec ce nouveau CRTC, pas besoin de programmation en assembleur pour avoir une image fullscreen (Oui oui, c’est faisable en BASIC !), on peut également faire des scrolls verticaux fluides en une seule commande. Cerise sur le gâteau, on peut découper l’écran en plusieurs parties. Cela permet par exemple d’afficher un HUD en haut de l’écran et faire scroller la partie du bas, sans nécessiter aucune techniques de synchronisation. C’est faisable en Basic ! Bien entendu si on passe en assembleur les possibilités sont décuplées. Mais vous l’aurez compris, de mon point de vue c’est l’accessibilité de ce composant via le Basic qui me semble être un atout.

Premiers pas

Je vous épargne la phase de retrait du CRTC d’origine et son remplacement par le 6345, c’est une manipulation classique. Une fois l’échange effectué et on rallume la machine, et là…

RAS.
On retombe sur l’écran normal du CPC. Rien de plus.
C’est une très bonne nouvelle : Cela veut dire que le 6345 se comporte comme un 6845 ordinaire. La rétrocompatibilité est respectée.

Pour une première prise de contact avec le 6345, je vous propose d’apprendre à détecter le composant. Ainsi, avant de taper dans les fonctions étendues on pourra s’assurer qu’elles sont bien disponibles sur la machine et afficher un petit messages pour tous les CRTCs bas de gamme ^_^

Comment est identifié le CRTC 5 par le programme original de détection de CRTC ? Comme un CRTC0. Il suffirait donc d’ajouter quelques lignes pour différencier le CRTC0 d’un CRTC5, à l’endroit du code où auparavant on indiquait qu’on avait trouvé un CRTC0.

Reste à trouver comment distinguer les deux CRTC. Différentier les 0, 1, 2 ou 4 était plutôt simple dans la mesure où toutes les infos figurent noir sur blanc dans le Compendium de Longshot. Le 5 n’a pas été étudié par le papa de Logon System : on n’a donc pour seule référence qu’un datasheet anglophone et plutôt minimaliste, fourni par le constructeur.

On a failli rater un bug !

Si vous avez lu la datasheet, vous avez peut-être fait le lien avec un détail plutôt gênant : Pour différentier le CRTC4 du CRTC0, on lit le registre 20 du composant. Or, sur le document technique (page 63) on voit que le registre 20 existe. Il porte le petit nom de « Screen 2 Start Address (L) ». Celui-ci est disponible en lecture et en écriture. Donc le test d’origine tombe à l’eau ! En effet, si avant de passer dans le code de détection quelqu’un a décidé de placer une valeur non nulle dans ce registre, on l’aurait lu durant le test. Notre CRTC5 aurait été identifié à tort comme un CRTC4 !

Il va donc falloir reprendre ce test également. On pourra être certain qu’il fonctionne correctement avec les trois types de CRTC. En d’autres termes, il faut qu’une lecture sur un port des CRTCs 0 ou 5 donnent à coup sûr zéro, et une valeur non nulle sur le CRTC4.

On a vu dans l’article précédent que pour lire le registre 12 sur le CRTC4 on pouvait lire l’adresse 12, mais aussi la 20 (C’est ce qu’on faisait dans le test à l’origine), 28, 36, 44, 52… et ainsi de suite, de 8 en 8.

Sur le CRTC0, le registre 12 se lit à l’adresse 12, 44, 76… Bref, de 32 en 32

Et le CRTC5, dans tout ça ? Le cas idéal serait qu’il fasse un modulo différent de 32 et 8. Quand on voit que la datasheet parle de 40 registres, on peut soupçonner un modulo 64. On va tester ! Le programme suivant va lire les 256 adresses de registres du CRTC, tout en présentant les données par paquet de 64.

Plaintext
10 MODE 1
20 for x=0 to 3
30 PRINT:PRINT
40 FOR y=0 to 63
50 OUT &BC00,x*64+y
60 PRINT HEX$(INP(&BF00),2);".";
70 NEXT y,x
80 WHILE INKEY$="":WEND

Le programme génère l’affichage suivant :

On avait bien supposé, ça semble se répéter tous les 64 adresses. Mais attendez, dans les deux derniers blocs on a un « 02 » au même endroit et « 00 » dans les deux premiers. Quand on relance le programme, les « 02 » changent de position, voire disparaissent carrément ! Une fonctionnalité cachée ? Pas du tout. Cet emplacement correspond au registre 31, qui est un registre de statut. Le bit « SB » est positionné à 1. La page 62 de la documentation indique que ce flag est positionné lorsque le CRTC génère un signal VSync. Intéressant ! Avec le CRTC original Amstrad a dû faire une bidouille supplémentaire pour qu’on puisse détecter la VSync via le port &F5. La fonctionnalité a été intégrée dans le 6345. Longshot sera probablement très intéressé par le flag « E » du même registre, qui semble indiquer la parité des frames en cas de mode entrelacé…

Forts de toutes ces informations, on va pouvoir faire le tri. On a besoin d’une adresse qui soit égale à 12+8*n (pour qu’on puisse lire une valeur non nulle sur le CRTC4), mais pas égale à 12+32*m (Pour qu’on voie un zéro sur CRTC0), et enfin qu’elle soit supérieure 39 et inférieure à 64 pour qu’on aie également un zéro sur CRTC5. Vous avez deux heures.

En deux minutes, on aura trouvé la valeur 52 : Sur CRTC4 on accède bien au registre 12, tandis qu’avec le zéro on accédera au registre 20 (inutilisé, donc zéro), et sur le 5 c’est le registre 52 (inutilisé également, toujours zéro) qui est adressé.

Dernière ligne droite

Il s’agit maintenant, une fois l’option « CRTC4 » éliminée, de différencier le CRTC0 du CRTC5. On va pouvoir jouer avec la même méthode, mais cette fois c’est plus simple : Il faut qu’on lise la valeur du registre 12 sur CRTC0, mais pas sur le CRTC4. Prenons par exemple la valeur 44. Sur CRTC0 cela correspond à l’adresse du registre 12. Sur le CRTC4, c’est un registre inutilisé qui est pointé (le… 44 ! On sait qu’on n’a que 40 registres sur ce composant, numérotés de 0 à 39. L’adresse 44 renverra immanquablement un 0).

Et voici donc la méthode ultime de détection de CRTC en Basic :

Plaintext
10 MODE 1:' On reinitialise l'ecran
20 OUT &BC00,12:IF INP(&BF00)=0 THEN GOTO 110
30 ' Si on est ici on a soit un CRTC0, soit un 4, soit un 5
40 OUT &BC00,52:IF INP(&BF00)=0 THEN GOTO 70
50 PRINT"crtc 4":END
60 ' Il reste à différencier le 0 du 5
70 OUT &BC00,44:IF INP(&BF00)=0 THEN GOTO 90
80 PRINT"crtc 0":END
90 PRINT"crtc 5":END
100 ' Si on est ici on a soit un CRTC1, soit un 2
110 OUT &BC00,31:IF INP(&BF00)=0 THEN GOTO 130
120 PRINT"crtc 1":END
130 PRINT"crtc 2":END

J’ai fait également une version plus compacte, qui peut même être mise sur une seule ligne :

Plaintext
10 OUT &BC00,12:A=SGN(INP(&BF00))
20 OUT &BC00,52:B=SGN(INP(&BF00))
30 OUT &BC00,44:C=SGN(INP(&BF00))
40 OUT &BC00,31:D=SGN(INP(&BF00))
50 CRTC=(2-D)*(1-A)+(4*B+(1-C)*(1-B)*5)*A
60 PRINT "crtc";CRTC

… Et pour finir, la version assembleur :

ASM
;==============================================================================
; CRTC_GET_TYPE
;------------------------------------------------------------------------------
; Gets the CRTC type
;------------------------------------------------------------------------------
; The register #12 of the CRTC is read, and should not be set to zero before
; using this macro
; A = Type Num (0, 1, 2, 4, 5). BC is changed
;==============================================================================
    macro CRTC_GET_TYPE
        ld bc,#bc00+12
        out (c),c
        ld bc,#bf00
        in a,(c)
        cp 0
        jr z,.group2
        ld bc,#bc00+52
        out (c),c
        ld bc,#bf00
        in a,(c)
        cp 0
        jr z,.group3
        ld a,4
        jr .end
.group3:
        ld bc,#bc00+44
        out (c),c
        ld bc,#bf00
        in a,(c)
        cp 0
        jr nz,.ctrc5
        xor a
        jr .end
.crtc5:
        ld a,5
        jr .end
.group2:
        ld bc,#bc00+31
        out (c),c
        ld bc,#bf00
        in a,(c)
        cp 0
        jr nz,.end
        ld a,2
        jr .end
        ld a,1
.end
    endm

Avec la Datasheet du CRTC6345 vous avez une bonne base pour tester des choses. Je compte vous proposer quelques billets de démonstration de divers effets graphiques en Basic, et peut-être même en assembleur si vous réclamez !

Edit : On m’a demandé où se procurer ce composant. Voici un lien vers le vendeur Amazon qui me l’a procuré : HD63B45P