Vous n'êtes pas sans savoir qu'au fil des années, les CPC ont été distribués avec diverses révisions du CRTC. En usage nominal cela serait sans doute passé totalement inaperçu, mais comme les CPCistes aiment bien titiller leur machine, on s'est rapidement retrouvé contronté à des problèmes de compatibilité CRTC !
“Horreur et damnatation ! Comment faire pour que mes routines hightech fonctionnent partout”, s'exclame le petit blond à lunette. “Gros malin”, lui répond alors le lapin rose, “il suffit de faire un test CRTC !”
Vous trouverez donc dans cette section diverses manières d'identifier les CRTC avec les explications qui vont bien.
— Basé sur les articles publiés dans Quasar CPC numéro 11, Perfectionnement à l'Assembleur, et numéros 12 et 21, Assembleur : Coding, par OffseT.
— Remis en forme et enrichi par Pulkomandy à partir d'informations issues d'Amslive numéros 16, 18 et 19 (articles de Madram) et du Grimware.
– À rédiger et à détailler.
– Rajouter une petite introduction.
Type | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
Ports &BExx et &BFxx |
|||||
Lecture des registres 12 and 13 sur le port &BFxx | Oui | Non8) | Non9) | Oui | Oui |
Décodage complet du numéro de registre sur le port &BFxx | Oui10) | Oui | Oui | Non11) | Non |
Lecture du registre 31 sur le port &BFxx | 0 | Hi-Z12) | 0 | Registre 15 | Registre 15 |
Lecture de l'état de la VBL sur le bit 5 du registre 10 sur le port &BFxx | Non | Non | Non | Oui | Oui |
Lecture du compteur de bloc sur le registre 11 sur le port &BFxx | Non | Non | Non | Oui | Oui |
Registre de status accessible sur le port &BExx (VBL, border) | Non13) | Oui | Non 14) | Non15) | Non16) |
Registres | |||||
R1 > R0 inhibe le border | Non | Oui | Non | Oui | Oui |
R2 + R3 > R0 | Décale l'écran17) | Décale l'écran18) | Pas de VBL | Décale l'écran19) | Décale l'écran20) |
R2 + R3 = R0 | Ok | Ok | Pas de VBL | Décale l'écran21) | Décale l'écran22) |
Le bit 7 du registre 3 change la durée de la VBL | Oui23) | Non24) | Non | Oui25) | Oui26) |
R6 = 0 crée des artéfacts à l'écran | Oui27) | Non28) | Oui29) | Non | Non |
Le registre 8 permet de passer en mode entrelacé (bits 0 et 1) | Buggé30) | Correctement31) | Directement | Buggé32) | Buggé33) |
Le registre 8 permet de décaler et de désactiver le border (bits 4 et 5) | Oui | Non | Non | Oui | Oui |
Astuces de demomakers | |||||
Activation du split-border | Avec le registre 834) | Avec le registre 635) | Impossible | Avec le registre 836) | Avec le registre 837) |
Validation de l'offset après reprogrammation des registres 12 et 13 | À l'écran suivant | Immédiatement38) | À l'écran suivant | À l'écran suivant | À l'écran suivant |
Validation des registres 9 et 4 après reprogrammation | Bufférisés | Immédiatement39) | Bufférisés | Bufférisés | Bufférisés |
Rupture ligne-à-ligne possible (R9 = R4 =0 ) | Oui | Oui | Non | Oui | Oui |
Valeur minimale du registre 0 | 1 | 0 | 040) | 0 | 0 |
Particularités du PPI41) | |||||
Programmer le PPI remet à 0 la valeur du port de donnée | Oui | Oui | Oui | Non42) | Oui |
Le port B du PPI peut être utilisé en sortie | Non | Non | Non | Oui | Non |
— Basé sur l'article publié dans Quasar CPC numéro 12, Assembleur : Coding, par OffseT.
– À saisir…
— Basé sur l'article publié dans Quasar CPC numéro 21, Assembleur : Coding, par OffseT.
Il y a quelques temps de cela, Targhan, m'avait demandé de lui fournir un test CRTC “neutre” pour la non moins célèbre Demo Iz Art. Ce test CRTC devait avoir pour particularité d'indentifier le CPC sans modifier les registres du CRTC (pas de saut d'écran, etc.). L'exercice étant assez ludique, après avoir réalisé ce petit programme afin que notre barbare puisse l'intégrer à la DIA, j'ai continué d'enrichir ce test d'une multitude de méthodes de détection diverses et variées. Ce code regroupant au final pas mal de petites choses fort sympathiques, nous avons décidé de le publier afin que tout le monde puisse en profiter.
Je ne vais pas vous détailler ici le fonctionnement du code car vous constaterez que le listing qui suit est largement commenté et, qu'avec un minimum d'efforts, vous parviendrez à le comprendre. Sachez juste que le test utilise plusieurs routines lancées consécutivement, chacune permettant d'identifier tel ou tel type de CRTC. Il y a de nombreuses redondances et toutes les routines ne sont absolument pas indispensables pour détecter avec certitude un type de CPC. Libre à vous d'utiliser celles qui vous paraissent les plus élégantes ou toutes si vous êtes un peu paranoïaque.
Notez également qu'il s'agit d'un test destiné à être lisible et il n'est pas particulièrement optimisé. Toutefois, il fait ce qu'il faut comme il faut. Libre à vous là aussi de maquiller ou même d'intégrer carrément les routines à votre code plutôt que d'avoir un test “à part”. Absolument aucun des tests publiés ici ne modifient le CRTC ou le Gate Array ; de ce fait, l'affichage n'est pas altéré durant la détection. Seul l'état de configuration du PPI est altéré par quelques tests. Le résultat cumulé des divers test permet non seulement d'identifier avec certitude un CRTC mais aussi de disqualifier tout CPC ayant donné des résultats incohérents d'un test à l'autre (ce qui sera le cas des CPC en panne, des CRTC non connus à ce jour et, accessoirement, des émulateurs).
Nous avons plusieurs types de tests. En premier lieu, nous avons ceux qui testent les lectures sur les registres du CRTC. Plusieurs registres, selon qu'ils soient accessibles en lecture ou pas, vont nous permettre de différencier divers CRTC (lecture de l'offset sur les registres 12 et 13, lecture de la dernière ligne de VBL sur le registre 10, lecture du bloc en cours de balayage sur le registre 11). On peut également vérifier comment se comporte la lecture sur les registres qui sont sensés ne rien renvoyer. Les valeurs renvoyées d'un type de CRTC à un autre étant différentes, on peut là aussi en tirer des conclusions intéressantes. Enfin, on va lire le port de statut du CRTC (&BExx
) qui nous permet par exemple de détecter le border uniquement sur CRTC type 1.
En complément de ces tests directement liés au CRTC, nous avons quelques tests qui scrutent le fonctionnement du PPI. En effet, sur CPC+, le PPI est émulé et a quelques différences de fonctionnement notables par rapport à son modèle (phase d'init, programmation I/O).
Pour chaque test, ce qu'il fait et ses conditions de bon fonctionnement sont décrites dans le listing.
Il ne s'agit pas d'un test exhaustif, en effet, tous ces tests ont pour particularité d'être neutres ; ils ne modifient pas la programmation du CRTC et donc rien ne “saute” ou ne change de couleur à l'écran. Si on décide de se dispenser de cette contrainte, il est possible d'enrichir encore ce programme d'autres routines de test (test du mode entrelacé, test de l'overflow du registre 2, test du mode IM 2, etc.). Toutefois, il s'agit d'une bonne base de départ qui, je le pense, vous permettra de découvrir des bits de test encore méconnus de nos chers CRTC.
Télécharger le listing au format Maxam 1.5
; Test CRTC version 3.0 ; (12/01/2005) par OffseT (Futurs') Nolist ; Réalisé entièrement sur un véritable CPC ; Plus aucun registre du CRTC n'est modifé durant les tests ! ; L'historique... ; Test CRTC version 1.1 ; - Test originel (23.02.1992) par Longshot (Logon System) ; ce test CRTC est celui crée par Longhost et utilisé dans la ; plupart des démos du Logon System. ; Test CRTC version 1.2 ; - Amélioration de la détection Asic (02/08/1993) par OffseT ; le test basé sur la détection de la page I/O Asic qui ; imposait de délocker l'Asic a été remplacé par un test ; des vecteurs d'interruption (mode IM 2). Le délockage de ; l'Asic n'est plus nécessaire. ; bug connu ; ce test ne fonctionne pas nécessairement sur un ; CPC customisé (notamment avec une interface gérant les ; interruptions en mode vectorisé) ou sur un CPC+ dont le registre ; Asic IVR a préalablement été modifié. ; - Correction du bug de détection CRTC 1 (18/06/1996) par OffseT ; sous certaines conditions de lancement le CRTC 1 était détecté ; comme étant un CRTC 0 (on peut constater ce bug dans The Demo ; et S&KOH). La méthode de synchronisation pour le test de détection ; VBL a été fiabilisée et ce problème ne devrait plus survenir. ; - Test CRTC version 2.0 ; - Ajout d'un test émulateur (03/01/1997) par OffseT ; ce test est basé sur la détection d'une VBL médiane lors de ; l'activation du mode entrelacé. Les émulateurs n'émulent pas ; cette VBL. ; limitation systématique ; ce test ne permet pas de distinguer ; un véritable CRTC 2 d'un CRTC 2 émulé. ; - Test CRTC version 3.0 ; - Retrait du test émulateur (20/12/2004) par OffseT ; ce test ne représente aucun intéret réel et a le désavantage ; de provoquer une VBL parasite pendant une frame. ; - Remplacement du test Asic (29/12/2004) par OffseT ; le nouveau test est basé sur la détection du bug de validation ; dans le PPI émulé par l'Asic plutôt que sur les interruptions ; en mode IM 2. C'est beaucoup plus fiable puisque ça ne dépend ; plus du tout de l'état du registre IVR ni des extensions gérant ; les interruptions connectées sur le CPC. Merci à Ram7 pour l'astuce. ; Limitation systématique ; l'état courant de configuration des ports ; du PPI est perdue, mais ça ne pose normalement aucun problème. ; - Remplacement du test CRTC 1 et 2 (29/12/2004) par OffseT ; le test originel de Longshot était basé sur l'inhibition de ; la VBL sur type 2 lorsque Reg2+Reg3>Reg0+1. Ce test modifiait ; les réglages CRTC et l'écran sautait pendant une frame. Il a été ; remplacé par un test basé sur la détection du balayage du border ; spécifique au type 1 qui n'a pas ces inconvénients. ; bug connu (rarissime) ; ce test renvoie un résultat erroné sur ; CRTC 1 si reg6=0 ou reg6>reg4+1... ce qui est fort improbable. ; - Modification du test CRTC 3 et 4 (29/12/2004) par OffseT ; le test ne modifie plus la valeur du registre 12. Toutefois ; il en teste la cohérence et vérifie également le registre 13. ; limitation (rare) ; ce test ne fonctionne pas si reg12=reg13=0. ; - Réorganisation générale des tests (29/12/2004) par OffseT ; chaque test est désormais un module qui permet, par le biais ; d'un système de masques de tests, de différencier les CRTC au ; fur et à mesure. ; - Retrait des dépendances d'interruption (29/12/2004) par OffseT ; plus aucun test ne fait usage des interruptions pour se synchroniser. ; - Ajout d'un test de lecture du port &BFxx (29/12/2004) par OffseT ; ce test permet de différencier les CRTC 1 et 2 des autres et vient ; en complément du test (historique) sur le timing VBL. ; limitation (rare) ; ce test ne fonctionne pas si reg12=re13=0. ; - Ajout d'un test de lecture des registres 4 et 5 (30/12/2004) par OffseT ; ce test donne théoriquement les mêmes résultats que le test ; initial de détection 3 et 4 basé sur des lectures sur le port ; &BExx ; il consiste à lire les registres 12 et 13 via leur miroir ; sur l'adressage des registres 4 et 5 sur type 3 et 4. ; limitation (rare) ; ce test ne fonctionne pas si reg12=reg13=0. ; - Ajout d'un test de lectures CRTC illégales (12/01/2005) par OffseT ; ce test vérifie qu'on obtient bien la valeur 0 en retour ; lors d'une tentative de lecture illégale d'un registre du ; CRTC en écriture seule. Ceci permet de différencier les types ; 0, 1 et 2 des types 3 et 4. ; - Ajout d'un test du port B du PPI (12/01/2005) par OffseT ; ce test vérifie si le port B peut-etre configuré en sortie. ; Ceci permet d'identifier le type 3. ; Limitation systématique ; l'état courant de configuration des ports ; du PPI est perdue, mais ça ne pose normalement aucun problème. ; - Ajout d'un test de détection de fin de VBL (12/01/2005) par OffseT ; ce test vérifie que le bit 5 du registre 10 du CRTC permet bien ; de détecter la dernière ligne de VBL sur les CRTC 3 et 4. Ceci ; permet de différencier les types 0, 1 et 2 des types 3 et 4. ; bug systématique ; si le bit 7 du registre 3 est à zéro (double VBL) ; le test renvoie un mauvais résultat. ; - Ajout d'un test de lecture du registre 31 (12/01/2005) par OffseT ; ce test vérifie sur la valeur en lecture renvoyée pour ce registre ; est non nulle. Si c'est le cas ça veut dire qu'on a lu soit un état ; de haute impédance (cas du type 1) soit le registre 15 qui était non ; nul (cas des types 3 et 4). On peut alors conclure que l'on a ni un ; type 0, ni un type 2. Si la valeur est nulle on ne peut rien conclure ; et le test est inopérant. ; limitation rarissime ; ce test ne fournit pas de résultat sur type 1 ; si l'état de haute impédance est altéré ; limitation courante ; ce test ne fournit pas de résultat sur types 3 et 4 ; si le registre 15 est nul (ce qui est la valeur par défaut) ; - Ajout d'un test de détection des blocs 0 et 1 (12/01/2005) par OffseT ; ce test vérifie que la détection des blocs 0 et 1 est fonctionnelle ; sur les types 3 et 4 à l'aide des flags du registre 11 du CRTC. Ceci ; permet de différencier les types 0,1,2 des 3,4. ; limitation systématique ; le registre 9 doit valoir 7 sinon le ; résultat est faux. ; Note ; une limitation décrit un cas dans lequel le test ne renvoie ; aucun résultat (il ne parvient pas à distinguer les CRTC) alors qu'un ; bug connu décrit un cas dans lequel le test peut renvoyer une mauvaise ; réponse (ce qui est beaucoup plus grave !). ; Les différents types de CRTC connus... ; 0 ; 6845SP ; sur la plupart des CPC6128 sortis entre 85 et 87 ; 1 ; 6845R ; sur la plupart des CPC6128 sortis entre 88 et 89 ; 2 ; 6845S ; sur la plupart des CPC464 et CPC664 ; 3 ; Emulé (CPC+) ; sur les 464 plus et 6128 plus ; 4 ; Emulé (CPC old) ; sur la plupart des CPC6128 sortis en 89 et 90. ; Le programme qui utilise le test CRTC... Org &9000 call testcrtc ; On lance le test CRTC ! add a,48 ; On affiche le type de CRTC call &bb5a ret ; On rend la main ; Le test CRTC... ; Attention ! Le CRTC doit être dans une configuration ; rationnelle pour que les tests fonctionnent (VBL et ; HBL présentes, registres 6 et 1 non nuls, bit 7 du ; registre 3 non nul, etc.) ; En sortie A contient le type de CRTC (0 à 4) ; A peut valoir &F si le CRTC n'est pas reconnu ; (mauvais émulateur CPC ou mauvaise configuration ; CRTC au lancement du test) TestCRTC ld a,&ff ld (typecrtc),a di ; CRTC 0,1,2,3,4 call testlongueurvbl ; 0,1,1,0,0 call testbfxx ; 0,1,1,0,0,alien call testbexx ; 0,0,0,1,1,alien call testfinvbl ; 0,0,0,1,1,alien call testr4r5 ; 0,0,0,1,1,alien call testregswo ; 0,0,0,1,1 call testbloc ; 0,0,0,1,1,alien call testborder ; 0,1,0,0,0 call testrazppi ; 0,0,0,1,0,alien call testportbppi ; 0,0,0,1,0 call testreg31 ; x,1,x,1,1 ei ld a,(typecrtc) cp crtc0:jr z,type_0 cp crtc1:jr z,type_1 cp crtc2:jr z,type_2 cp crtc3:jr z,type_3 cp crtc4:jr z,type_4 ld a,&f:ret Type_0 ld a,0:ret Type_1 ld a,1:ret Type_2 ld a,2:ret Type_3 ld a,3:ret Type_4 ld a,4:ret ; Test basé sur la mesure de la longueur de VBL ; Permet de différencier les types 1,2 des 0,3,4 ; Bug systématique ; si le bit 7 du registre 3 est à zéro (double VBL) ; le test renvoie un mauvais résultat TestLongueurVBL ld b,&f5 ; Boucle d'attente de la VBL SyncTLV1 in a,(c) rra jr nc,synctlv1 NoSyncTLV1 in a,(c) ; Pre-Synchronisation rra ; Attente de la fin de la VBL jr c,nosynctlv1 SyncTLV2 in a,(c) ; Deuxième boucle d'attente rra ; de la VBL jr nc,synctlv2 ld hl,140 ; Boucle d'attente de WaitTLV dec hl ; 983 micro-secondes ld a,h or l jr nz,waittlv in a,(c) ; Test de la VBL rra ; Si elle est encore en cours jp c,type12 ; on a un type 1,2... jp type034 ; Sinon on a un type 0,3,4 ; Test basé sur la lecture des registres 12 et 13 ; sur le port &BFxx ; Permet de différencier les types 0,3,4 et 1,2 ; Limitation rare ; si reg12=reg13=0 le test est sans effet TestBFxx ld bc,&bc0c ; On sélectionne le reg12 out (c),c ld b,&bf ; On lit sa valeur in a,(c) ld c,a ; si les bits 6 ou 7 sont and &3f ; non nuls alors on a un cp c ; problème jp nz,typealien ld a,c or a ; si la valeur est non nulle jp nz,type034 ; alors on a un type 0,3,4 ld bc,&bc0d out (c),c ; On sélectionne le reg13 ld b,&bf in a,(c) ; On lit sa valeur or a ; Si la valeur est non nulle jp nz,type034 ; alors on a un type 0,3,4 ret ; Test basé sur la lecture des registres 12 et 13 ; à la fois sur les ports &BExx et &BFxx ; Permet de différencier les types 0,1,2 des 3,4 ; Limitation rare ; si reg12=reg13=0 le test est sans effet TestBExx ld bc,&bc0c ; On sélectionne le registre 12 out (c),c ; On compare les valeurs sur call cpbebf ; les ports &BExx et &BFxx push af ; (on sauve les flags) ld b,a ; Si le bit 6 ou 7 de la valeur and &3f ; lue pour &BFxx est non nul cp b ; alors on a un problème call nz,typealien pop af ; (on récupère les flags) jp nz,type012 ; Si elles sont différentes xor a ; on a un type 0,1,2 cp c ; Si elles sont égales et jp nz,type34 ; non nulles on a un type 3,4 ld bc,&bc0d ; On sélectionne le registre 13 out (c),c ; On compare les valeurs sur call cpbebf ; les ports &BExx et &BFxx jp nz,type012 ; Si elles sont différentes xor a ; on a un type 0,1,2 cp c ; Si elles sont égales et jp nz,type34 ; non nulles on a un type 3,4 ret CPBEBF ld b,&be ; On lit la valeur sur &BExx in a,(c) ld c,a ; On la stocke dans C inc b in a,(c) ; On lit la valeur sur &BFxx cp c ; On la compare à C ret ; Test basé sur la RAZ du PPI ; Permet de différencier les types 0,1,2,4 du 3 ; Limitation systématique ; l'état courant de configuration des ports ; du PPI est perdu TestRAZPPI ld bc,&f782 ; On configure le port C out (c),c ; en sortie dec b ld c,&f ; On place une valeur sur out (c),c ; le port C du PPI in a,(c) ; On vérifie si la valeur est cp c ; toujours là en retour jp nz,typealien ; sinon on a un problème inc b ld a,&82 ; On configure de nouveau out (c),a ; le mode de fonctionnement dec b ; des ports PPI in a,(c) ; On teste si la valeur placée cp c ; sur le port C est toujours là jp z,type3 ; Si oui on a un type 3 or a ; Si elle a été remise à zéro jp z,type0124 ; on a un type 0,1,2,4 jp typealien ; Sinon on a un problème ; Test basé sur la détection du balayage des lignes ; hors border ; Permet d'identifier le type 1 ; Bug connu rarissime ; si reg6=0 ou reg6>reg4+1 alors le test est faussé ! TestBorder ld b,&f5 NoSyncTDB1 in a,(c) ; On attend un peu pour être rra ; sur d'être sortis de la VBL jr c,nosynctdb1 ; en cours du test précédent SyncTDB1 in a,(c) ; On attend le début d'une rra ; nouvelle VBL jr nc,synctdb1 NoSyncTDB2 in a,(c) ; On attend la fin de la VBL rra jr c,nosynctdb2 ld ix,0 ; On met à zéro les compteurs ld hl,0 ; de changement de valeur (IX), ld d,l ; de ligne hors VBL (HL) et ld e,d ; de ligne hors border (DE) ld b,&be in a,(c) and 32 ld c,a SyncTDB2 inc de ; On attend la VBL suivante ld b,&be ; en mettant à jour les divers in a,(c) ; compteurs and 32 jr nz,border inc hl ; Ligne de paper ! jr noborder Border ds 4 NoBorder cp c jr z,nochange inc ix ; Transition paper/border ! jr change NoChange ds 5 Change ld c,a ds 27 ld b,&f5 in a,(c) rra jr nc,synctdb2 ; On boucle en attendant la VBL db &dd:ld a,l ; Si on n'a pas eu juste deux cp 2 ; transitions alors ce n'est jp nz,type0234 ; pas un type 1 jp type1 ; Pour plus de fiabilité au ; regard de l'état de haute ; impédance sur les CRTC autres ; que le type 1 on pourrait ; vérifier ici que HL vaut ; reg6*(reg9+1) mais ça impose ; de connaitre au préalable la ; valeur de ces deux registres ; Test basé sur la lecture des registres 4 et 5 ; Permet de différencier les types 0,1,2 des 3,4 ; Limitation rare ; si reg12=reg13=0 le test est sans effet TestR4R5 ld bc,&bc0c ; On sélectionne le registre 12 out (c),c ; On compare les valeurs en call cprhrl ; retour sur le port &BFxx push af ; On sauve les flags ld b,a ; Si le bit 6 ou 7 de la valeur and &3f ; lue pour &BFxx est non nul cp b ; alors on a un problème call nz,typealien pop af ; On récupère les flags jp nz,type012 ; Si elles sont différentes xor a ; on a un type 0,1,2 cp c ; Si elles sont égales et jp nz,type34 ; non nulles on a un type 3,4 ld bc,&bc0d ; On sélectionne le registre 13 out (c),c ; On compare les valeurs en call cprhrl ; retour sur le port &BFxx jp nz,type012 ; Si elles sont différentes xor a ; on a un type 0,1,2 cp c ; Si elles sont égales et jp nz,type34 ; non nulles on a un type 3,4 ret CPRHRL ld b,&bf ; On lit la valeur du registre in a,(c) ; High sur &BFxx ld b,&bc ; Sélection du registre Low res 3,c ; On passe sur le registre Low out (c),c ld c,a ; On la stocke dans C ld b,&bf in a,(c) ; On lit la valeur sur &BFxx cp c ; On la compare à C ret ; Test basé sur la valeur de retour sur les registres ; CRTC en écriture seule ; Permet de différencier les types 0,1,2 des types 3,4 ; Aucune limitation/bug connus TestRegsWO ld de,0 ; On lance le parcours des ld c,12 ; registres 0 à 11 avec call cumulereg ; cumul de la valeur retour xor a ; Si le résultat cumulé de cp d ; la lecture est non nul jp nz,type34 ; alors on a un type 3,4 jp type012 ; Sinon, c'est un type 0,1,2 CumuleReg LoopTRI ld b,&bc ; On sélectionne le out (c),e ; registre "E" ld b,&bf ; On lit la valeur in a,(c) ; renvoyée en retour or d ; On la cumule dans D avec ld d,a ; les lectures précédentes inc e ; On boucle jusqu'au ld a,e ; registre "C" cp c jr nz,looptri ret ; Test basé sur la possibilité de programmer le port B ; en sortie ; Permet d'identifier le type 3 ; Limitation systématique ; l'état courant de configuration des ports ; du PPI est perdu TestPortBPPI ld b,&f5 SyncTPBP1 in a,(c) rra jr nc,synctpbp1 NoSyncTPBP1 in a,(c) ; Pre-Synchronisation rra ; Attente de la fin de la VBL jr c,nosynctpbp1 ld bc,&f782 ; On configure le port B out (c),c ; du PPI en entrée ld b,&f5 ; On lit la valeur présente in a,(c) ; sur le port B puis on xor 254 ; la modifie judicieusement ld e,a ; et on la stocke dans E ld d,&f5 ld bc,&f780 ; On configure le port B out (c),c ; du PPI en sortie ld b,d ; On y envoie la valeur out (c),e ; stockée dans E in a,(c) ; On relit le port B ld bc,&f782 ; On reconfigure le port B out (c),c ; du PPI en entrée cp e ; Si la valeur E a été lue jp z,type0124 ; alors on a type 0,1,2,4 jp type3 ; Sinon on a un type 3 ; Test basé sur la détection de la dernière ; ligne de VBL ; Permet de différencier les types 0,1,2 des 3,4 ; Bug systématique ; si le bit 7 du registre 3 est à zéro (double VBL) ; le test renvoie un mauvais résultat) TestFinVBL ld bc,&bc0a ; On sélectionne le out (c),c ; registre 10 du CRTC ld b,&f5 NoSyncTFV1 in a,(c) ; Pre-Synchronisation rra ; Attente de la fin de la VBL jr c,nosynctfv1 ld b,&bf ; On lit l'état du registre 10 in a,(c) and 32 ; Si le bit5 est nul alors jp z,type012 ; on a un type 0, 1 ou 2 ld b,&f5 SyncTFV2 in a,(c) ; Boucle d'attente de la VBL rra jr nc,synctfv2 ld hl,55 ; Boucle d'attente de WaitTfV dec hl ; 388 micro-secondes ld a,h or l jr nz,waittfv ld b,&bf ; On lit l'état du registre 10 in a,(c) and 32 ; Si le bit5 est nul jp z,typealien ; on a un problème ld b,13 ; Boucle d'attente de djnz $ ; 54 micro-secondes ld b,&bf ; On lit l'état du registre 10 in a,(c) and 32 ; Si le bit5 est non nul jp nz,typealien ; on a un problème ld b,13 ; Boucle d'attente de djnz $ ; 54 micro-secondes ld b,&bf ; On lit l'état du registre 10 in a,(c) and 32 ; Si le bit5 est non nul jp nz,type34 ; on a un type 3 ou 4 jp typealien ; Sinon on a un problème ; Test basé sur le statut particulier du registre 31 ; Permet d'identifier les types 1, 3 et 4 ; Limitation rarissime ; ce test ne fournit pas de résultat sur type 1 ; si l'état de haute impédance est altéré ; Limitation courante ; ce test ne fournit pas de résultat sur types 3 et 4 ; si le registre 15 est nul (ce qui est la valeur par ; défaut) TestReg31 ld bc,&bc1f ; On sélectionne le registre 31 out (c),c ; et on fait une tentative de ld b,&bf ; lecture sur le port &BFxx in a,(c) ; Si on a une valeur non nulle jp nz,type134 ; alors c'est un type 1,3,4 ret ; sinon on ne peut rien ; conclure ; Test basé sur la détection des blocs 0 et 1 ; Permet de différencier les types 0,1,2 des 3,4 ; Limitation systématique ; le registre 9 doit valoir 7 sinon le résultat ; est faux TestBloc ld bc,&bc0b ; On sélectionne le out (c),c ; registre 10 du CRTC ld b,&f5 NoSyncTB1 in a,(c) ; Pre-Synchronisation rra ; Attente de la fin de la VBL jr c,nosynctb1 SyncTB2 in a,(c) ; Boucle d'attente de la VBL rra jr nc,synctb2 NoSyncTB2 in a,(c) rra ; Attente de la fin de la VBL jr c,nosynctb2 ld b,&bf ; On lit l'état du registre 11 in a,(c) ; (on est sur le bloc 1) ld d,a ld b,14 ; On attend 58 micro-secondes djnz $ ld b,&bf in a,(c) ; On lit l'état du registre 11 ld c,a ; (on est sur le bloc 2) ld b,96 ; On attend 386 micro-secondes djnz $ ld b,&bf in a,(c) ; On lit l'état du registre 11 ld e,a ; (on est sur le bloc 0) or d ; Si on n'a pas lu une valeur or e ; nulle à chaque fois alors jr nz,tbactif ; on peut continuer jp type012 ; Sinon on a un type 0, 1 ou 2 TBActif ld a,&a0 ; Si pour le bloc 0 on n'a pas and e ; bit7=0 et bit5=0 jp nz,typealien ; alors on a un problème ld a,&a0 ; Si pour le bloc 1 on n'a pas and d ; bit7=1 et bit5=1 cp &a0 ; alors on a un problème jp nz,typealien ld a,&a0 ; Si pour le bloc 2 on n'a pas and c ; bit7=0 et bit5=1 cp &20 ; alors on a un problème jp nz,typealien jp type34 ; Sinon on a un type 3 ou 4 ; Routines de typage CRTC0 Equ 1 CRTC1 Equ 2 CRTC2 Equ 4 CRTC3 Equ 8 CRTC4 Equ 16 Type012 ld a,(typecrtc) and crtc0+crtc1+crtc2 ld (typecrtc),a ret Type0124 ld a,(typecrtc) and crtc0+crtc1+crtc2+crtc4 ld (typecrtc),a ret Type0234 ld a,(typecrtc) and crtc0+crtc2+crtc3+crtc4 ld (typecrtc),a ret Type034 ld a,(typecrtc) and crtc0+crtc3+crtc4 ld (typecrtc),a ret Type1 ld a,(typecrtc) and crtc1 ld (typecrtc),a ret Type12 ld a,(typecrtc) and crtc1+crtc2 ld (typecrtc),a ret Type134 ld a,(typecrtc) and crtc1+crtc3+crtc4 ld (typecrtc),a ret Type3 ld a,(typecrtc) and crtc3 ld (typecrtc),a ret Type34 ld a,(typecrtc) and crtc3+crtc4 ld (typecrtc),a ret TypeAlien xor a ld (typecrtc),a ret ; Variables List TypeCRTC db &ff
&BFXX
&BFxx