Auteur Sujet: Etude/Réalisation d'un générateur de mires 15/24/31 kHz  (Lu 26158 fois)

Hors ligne gc339

  • Beta Testeur
  • *
  • Messages: 2224
  • Localisation: Lyon
    • Voir le profil
Etude/Réalisation d'un générateur de mires 15/24/31 kHz
« le: Dimanche 27 Janvier 2013, 15:34:59 pm »
  • J'utilise actuellement une version simplifiée du générateur vidéo décrit par Marcello Maggi, il permet de générer simplement 4 mires différentes en 15 kHz entrelacé : barres colorées, quadrillage, points ainsi qu'une image entièrement blanche :

       


    Le dossier complet ou les fichiers isolés du générateur vidéo  sont disponibles à partir de plusieurs sites sur le net, il suffit de faire une recherche avec les mots clef "Marcello Maggi" et "video pattern generator".
    A défaut voici le dossier pdf original sauvegardé ici sur le serveur Gamoover : http://www.gamoover.net/gc339/VidPatGen.pdf



    Le générateur réalisé à partir de cette description :


    Seul le pic 16F84 avec le programme original a été conservé, l'encodeur PAL inutile a été remplacé par un circuit intégré genre 26LS31 qui bufferise la synchro et les signaux RVB, ce qui me permet d'avoir deux sorties pour chaque signal : une normale (positive ) et la deuxième inversée (négative ).
    Les deux switches Secme permettent de choisir une des 4 mires possibles.



    Le problème est que ce générateur ne délivre que du 15 kHz et qu'il faudrait pouvoir générer les mêmes mires en 24 et en 31 kHz pour pouvoir tester les moniteurs multifréquences.
    De plus la 4ème mire, celle affichant un écran uniformément blanc, n'est pas d'une très grande utilité. Il serait préférable de la remplacer par une mire alternant images ou larges bandes noires et blanches pour vérifier la stabilité de la THT :

       

    En effet, une image noire demande aucun courant au bloc THT alors qu'une image uniformément blanche lui en soutire un maximum. Si le bloc THT est sous dimensionné ou mal en point, la tension s'affaissera avec le courant délivré, les électrons seront alors moins accélérés et seront donc plus facilement déviés par les bobinages du yoke, l'image affichée augmentera de taille et les zones blanches seront moins lumineuses.



    L'objet de ce wip est de réaliser un générateur vidéo capable de délivrer les 3 mires de base plus la mire alternant zones blanches et noires et ceci aux 3 fréquences utilisées en arcade, 15, 24 et 31 kHz.

    Le document de départ sera ce tableau extrait du "Service Manual" du moniteur MS-2931 donnant les timings des différents signaux vidéo, les trames sont toutes identiques, pas de trames paires et impaires car il n'y a pas d'entrelacement:



    Seules les trois premières lignes horizontales du tableau sont utiles car elles concernent les signaux vidéo issus de systèmes Sega, ils serviront donc de référence pour l'élaboration de ce générateur.
    Les 3 dernières lignes indiquent les timings correspondant à la taille d'image maximum que ce moniteur peut afficher.
    Chaque ligne comporte deux cellules dans certaines colonnes verticales :
    • Les cellules du haut concerne la ligne. Elles indiquent la durée de l'impulsion de synchronisation ligne (Sync ), celle du contenu correspondant aux pixels affichés (Video ) avec son positionnement dans la ligne (B.P. pour Back Porch ), le tout exprimé en microsecondes.
    • Les cellules du bas concerne la trame. Elles délivrent la durée de l'impulsion de synchronisation (Sync ), la taille de l'image affichée  (Video )avec son positionnement dans la trame (B.P.), le tout exprimé en nombre de lignes.
    Ainsi pour la première ligne du tableau décrivant un signal à 15 kHz :
    • L'impulsion de synchronisation ligne dure 4,75 µs, suivie 6,45 µs après par 49,17 µs du contenu à afficher. La ligne dure au total 63,56 µs et il reste donc 63,56 - 4,75 - 6,45 - 49,17 soit 3,19 µs entre la fin du contenu affiché et le début de l'impulsion ligne suivante.
    • L'impulsion de synchronisation trame dure 3 lignes, suivie 23 lignes vides après par 224 lignes de l'image à afficher. La trame dure au total 263 lignes et il reste donc 263 - 3 - 23 - 224 soit 13 lignes vides entre la fin de l'image affichée et le début de l'impulsion trame suivante



    Les timings du signal vidéo à 15 kHz délivré par le précédent générateur étaient basés sur la durée des instructions du programme exécuté par le PIC 16F84 quitte à ajouter des instructions "nop" inopérantes pour ajuster les durées.
    Ici les timings des lignes sont donnés à 0,01 µs près soit 10 ns ce qui correspondrait à une fréquence d'horloge de 100 Mhz pour un micro-contrôleur capable d'exécuter une instruction par cycle.
    Le PIC16F84 du précédent générateur en est bien incapable avec sa plus grande fréquence d'horloge à 20 MHz, c'est pourquoi un SX28AC Scenix/Parallax/Ubicom lui sera substitué.
    Ce micro-contrôleur SX28, en mode turbo, est capable d'exécuter une instruction par cycle d'horloge. Un SX28AC de base fonctionne parfaitement à une fréquence d'horloge de 50 MHz, certains exemplaires triés fonctionnent à 75 MHz voir même 100 MHz.
    Avec un SX28AC de série cadencé à 50 MHz il sera donc possible d'exécuter une instruction toutes les 20 ns et ainsi de coller à ± 10 ns près au timing des signaux d'une ligne.


    Le brochage du SX28AC avec son boîtier oscillateur externe.
    20 ports d'E/S sont disponibles : 4 pour le port RA, 8 pour les ports RB et RC.



    Le timing des signaux à 15 kHz sous forme graphique, page I-5 du "Service Manual" du moniteur MS-2931 :



    Les quatre intervalles de temps exprimés en µs et recalculés en pas de 20 ns :
    • La synchronisation horizontale : 4,75 µs soit 4750 ns donc 237,5 pas.
    • Le palier de suppression arrière (back porch ): 6,45 µs donc 322,5 pas.
    • Le contenu à afficher : 49,17 µs donc 2458,5 pas.
    • Le palier de suppression avant (front porch ): 3,19 µs donc 159,5 pas.
    Soit un total de 3178 pas de 20 ns pour une ligne complète. Un demi pas correspond en fait à 10 ns

    Comme un pas correspondra à un cycle du SX28AC, chaque intervalle de temps doit être un nombre entier et il est préférable d'arrondir au nombre de pas immédiatement supérieur les intervalles de temps les plus courts , quitte à minorer les intervalles les plus longs, ainsi donc :
    • De 237,5 pas la synchronisation sera arrondie à 238.
    • De 322,5 pas le palier arrière sera arrondi à 323.
    • De 159,5 pas le palier avant sera arrondi à 160.
    • Il reste donc 3178 - (238 + 323 + 160) pas pour le contenu à afficher, soit 2457 pas.
    Hors 2457 n'est pas divisible par 8, pourquoi par 8? Par ce que la mire à barre colorée comporte 8 barres. Ce qui ferait 307,125 pour chaque barre, si l'on arrondi à 307 pas par barre le total passe à 2456 pas et il faut soit augmenter d'un pas le palier avant soit le faire pour la dernière barre. En réalité cela n'a aucune importance pour cette mire car le palier avant est confondu avec la dernière barre puisque celle ci est de couleur noire :



    Comme on peut le voir sur ce dessin représentant les 3 signaux RVB d'une mire à barre colorée, ces signaux ont une amplitude nulle quand la dernière barre, la noire, est affichée. Elle est donc au même niveau que celui de l'intervalle de temps séparant cette barre de l'impulsion de synchronisation, autrement dit elle est confondue avec le palier de suppression avant.



    Le timing des signaux à 24 kHz, moitié supérieure de la page I-6 du "Service Manual" du moniteur MS-2931 :



    Les quatre intervalles de temps exprimés en µs et recalculés en pas de 20 ns :
    • La synchronisation horizontale : 3,00 µs donc 150 pas.
    • Le palier de suppression arrière (back porch ): 4,44 µs donc 222 pas.
    • Le contenu à afficher : 30,69 µs donc 1534,5 pas.
    • Le palier de suppression avant (front porch ): 2,87 µs donc 143,5 pas.
    Soit un total de 2050 pas de 20 ns pour une ligne complète.

    Le nombre entier 1534 n'est pas divisible par 8, le plus proche multiple étant de 1536. En portant à 192 pas (1536 ÷ 8 = 192) l'intervalle de temps correspondant à chaque barre colorée, le palier de suppression avant devra alors être raboté de 1,5 pas soit 30 ns, ce qui n'est pas un problème puisque la dernière barre est confondue avec le palier de suppression avant.
    Les intervalles de temps correspondant à l'impulsion de synchronisation ligne et au palier de suppression arrière restent inchangés puisque ce sont déjà des nombres entiers de pas, ainsi donc :
    • L'impulsion de synchronisation reste inchangée à 150 pas.
    • Le palier arrière reste inchangé à 222.
    • Le contenu à afficher est modifié à 8 × 172 soit 1536 pas.
    • Le palier avant est minoré de 1,5 pas, sa nouvelle valeur est de 142 pas soit 2,84 µs au lieu de 2,87 µs, ce qui représente une erreur de 1%.



    Le timing des signaux à 31 kHz, moitié inférieure de la page I-6 du "Service Manual" du moniteur MS-2931 :



    Les quatre intervalles de temps exprimés en µs et recalculés en pas de 20 ns :
    • La synchronisation horizontale : 3,58 µs donc 179 pas.
    • Le palier de suppression arrière (back porch ): 1,75 µs donc 87,5 pas.
    • Le contenu à afficher : 25,92 µs donc 1296 pas.
    • Le palier de suppression avant (front porch ): 0,33 µs donc 16,5 pas.
    Soit un total de 1579 pas de 20 ns pour une ligne complète.

    Le nombre entier 1296 est un multiple de 8, (1296 ÷ 8 = 162), il n'y a rien à retoucher. Par contre aucune durée des paliers de suppression ne correspond à un nombre entier et comme il est préférable de majorer le nombre le plus faible (16,5 pour le palier avant ) et de minorer le plus grand (87,5 pour le palier arrière ), cela aura pour effet négligeable de recentrer l'image affichée de 0,5 % ÷ 1296 soit 0,26 vers la gauche. Ainsi donc :
    • L'impulsion de synchronisation reste inchangée à 179 pas.
    • Le palier arrière est tronqué de 10 ns, sa nouvelle valeur est de 87 pas au lieu de 87,5.
    • Le contenu à afficher est reste inchangé, 8 × 162 soit 1296 pas.
    • Le palier avant est allongé de 10 ns, sa nouvelle valeur est de 17 pas au lieu de 16,5.



    Le futur générateur en chantier :



    Le circuit prépercé remplace le couvercle d'un boîtier de 120 × 75 × 55. Le boîtier du générateur précédent était plus petit puisqu'il ne mesurait que 90 × 60 × 40.

    Pour l'instant ne sont implantés que :
    • Dans le coin supérieur gauche : le jack pour connecter le bloc secteur de l'alimentation extérieure
    • Au milieu toujours en haut, le régulateur 5 volts avec son radiateur.
    • En dessous à gauche, le module oscillateur 50 MHz récupéré sur une épave.
    • Toujours en dessous et à droite, le micro-contrôleur SX28AC Parallax.
    Seront implantés par la suite :
    • Une embase HD-15 femelle pour sortir les signaux vidéo vers le moniteur en test.
    • Une batterie de 4 dip-switches, 2 pour choisir la mire et 2 autres pour la fréquence.
    • ...

    « Modifié: Mardi 08 Septembre 2015, 15:11:40 pm par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne kos71

    • Formica Lover
    • Game Cheater
    • *
    • Messages: 2403
    • Localisation: Chnord bye bye burgundy
    • Epaviste
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #1 le: Dimanche 27 Janvier 2013, 18:42:51 pm »
  • oulalalal ça me plait bien ça . très bonne idée . je vais suivre ce post de pret car c 'est ideal pour le test d'écran . Il va m'en falloir un vu le nombre de wip que eyeshield me ramène en ce moment.

    bon courage a toi pour la suite et surtout merci pour le partage de l'info et du concept
    JE RECHERCHE UNE BORNE KILLER INSTINCT

    @home: Flip TMNT, flip hurricane, Flip big guns, flip dracula,Flip F14,robocop, lw3,jokerz, rockybullwinckle,star wars De,sttng,dr who,tales from the crypt,jurassic park,laser war,gateway,tommy the who,baby pacman./cab=Mortal kombat 2,hang on DX, time crisis, hotd,pupitre fighting vipers, Naomi 1,  cocktail RP,cocktail missile command , cocktail "taito", cocktail space trek,cocktail galaxian,cocktail DE deco,cocktail SI., twin sega rally, OUT RUN,cockpit OT turbo, Virtua cop, Euro 40, astro city Blast city,mvs4u,namco exceleena red,madonna,aerocityx2,sega city ,bandido et afterburner dx

    Hors ligne Persecutor

    • Pampers Dealer
    • Hi-Score Buster
    • *
    • Messages: 3184
    • Localisation: FR 33 BDX
    • Presque Racer
      • Voir le profil
      • The Arcade DataBase
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #2 le: Lundi 28 Janvier 2013, 10:54:56 am »
  • C'est vraiment une super idée  ^-^

    et un sacré taff a venir  <:)

    Les jeux de moto c'est nul ! Y'a pas de volant ...

    Les bornes japonaises c'est comme les vaisseaux de la prélogie star wars,
    c'est beau, lisse et parfaitement fonctionnel;
    Alors que les bornes old school c'est un peu comme le Faucon Millenium qui passe jamais en vitesse lumière,
    c'est chiant mais c'est tellement plus attachant ...

    WIP s | Jeutel 25" RGB Jamma | Générique 17" 31khz | Mini BarTop TFT | Race Pod PC |

    http://persecutor.tamdb.net

    Hors ligne Eko

    • VIP
    • *
    • Messages: 1737
    • Localisation: L.A. en isAIR (38)
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #3 le: Lundi 28 Janvier 2013, 12:03:49 pm »
  • Ah Ahhhhh c'est reparti pour un projet qui va bien !!!!!!
     <:) <:)

    Bon, on se voit quand  =?= =?=  :D :D
    Faut bien qu'on se fasse une bise pour la nouvelle année quand même  ;)
    Et puis j'ai un truc à te faire visiter  :D j'ai fini... :D
    Le RT, le WIP, des drogues dures ça nan ?

    -RT Jeutel Mint !          -RT Twin STC          -WIP Twin STC         -RT Mini Jeutel    
    -WIP Noami White       -WIP Noami Black    -WIP Gameroom      -WIP Mini Jeutel

    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #4 le: Lundi 28 Janvier 2013, 15:21:17 pm »
  • Autant commencer par le programme de la mire à barres colorées, c'est le plus simple!



    Comme on peut le voir sur le dessin, les 8 couleurs de la mire à barre colorées sont générées à partir des 3 couleurs de base, leur présence ou leur absence détermine la teinte finale.
    Un niveau logique 1 pour une couleur donnée équivaut à sa présence alors que le niveau 0 équivaut à son absence.
    Dans le langage assembleur du SX28A, les couleurs peuvent être définies en binaire comme suit :

    ; Définition des couleurs de la mire à barres colorées
       Black   EQU   %000
    BlueEQU%001   ; Bit 2°
    RedEQU%010; Bit 2¹
    GreenEQU%100; Bit 2²
    MagentaEQUBlue+Red
    CyanEQUBlue+Green
    YellowEQURed+Green
    WhiteEQUBlue+Red+Green

    Le port RA du SX28AC étant arbitrairement choisi pour émettre les signaux de couleur, 3 de ses ports élémentaires se retrouvent affectés de fait suite à la définition qui a été donnée ci-dessus pour les couleurs de base :
    • RA0, patte n° 6, niveau logique de la couleur Bleue.
    • RA1, patte n° 7, niveau logique de la couleur Rouge.
    • RA2, patte n° 8, niveau logique de la couleur Verte.

    Ainsi pour émettre une couleur ou en changer, l'instruction suivante pourra être employée :
       MOV   RA,#Cyan   ; Émission de la couleur Cyan

    Le problème avec cette simple instruction est qu'elle affecte les 4 ports élémentaires du port RA dont fait partie RA3 qui n'est pas concerné par les informations de couleur. Il est préférable d'utiliser la séquence d'instructions suivante même si elle nécessite quelques cycles machine supplémentaires (W est le registre de travail ou accumulateur du micro-contrôleur ) :
       MOV   W,RA   ; Lecture du port RA
    ANDW,#%1000; Effacement des 3 bits de couleur
    ORW,#Cyan; Positionnement des seuls bits impactés par la couleur Cyan
    MOVRA,W; Émission de cette nouvelle couleur



    Le câblage entre le SX28AC et l'embase HD-15 femelle pourrait être réalisé comme suit :



    Le buffer LS367A inséré entre les 3 ports du SX28AC et l'embase HD-15 permet de le protéger contre toute fausse manip. Il vaut mieux suicider un vulgaire LS367A coûtant une fraction d'euro que de bousiller le micro-contrôleur. D'ailleurs, il faudra certainement insérer un atténuateur commutable entre les sorties du LS367A et l'embase HD-15 car, selon les exigences du moniteur MS-2931, l'amplitude des signaux vidéo doit être limitée à 0,7 volt sur 75 ? en 24 et en 31 kHz. Ceci est à vérifier pour tout autre moniteur.



    Dans le cas de la mire à barres colorées un délai doit être mis en oeuvre entre chaque changement de couleur, cette temporisation déterminera la largeur des barres verticales :

    Exemple cette séquence d'instructions :
     
    Start   MOV   RA,#White   ; Émission de la barre Blanche
    CALLDelay
    MOVRA,#Yellow; Émission de la barre Jaune
    CALLDelay
    MOVRA,#Cyan; Émission de la barre Cyan
    CALLDelay
    MOVRA,#Green; Émission de la barre Verte
    Et ainsi de suite pour les autres couleurs...

    Comme évoqué dans le message précédent, ces délais ou temporisations sont basées sur la durée que met le micro-contrôleur à exécuter une bouclette de programme. Généralement on utilise une variable, préalablement déclarée en entête de programme, qui sera pré-positionnée pour être ensuite décrémentée jusqu'à ce que sa valeur soit nulle. Exemple :

    Start   MOV   RA,#White   ; Émission de la barre Blanche
    MOVCounter,#Delay; Initialisation du compteur
    LoopWhiteDJNZCounter,LoopWhite
    NOP
    NOP
    MOVRA,#Yellow; Émission de la barre Jaune
    MOVCounter,#Delay; Initialisation du compteur
    LoopYellowDJNZCounter,LoopYellow
    NOP
    NOP
    MOVRA,#Cyan; Émission de la barre Cyan
    Et ainsi de suite pour les autres couleurs...

    L'instruction DJNZ (Decrement and Jump if Non Zero) est celle de la bouclette, elle décrémente la variable "Counter" et reboucle à l'adresse "LoopWhite", c'est à dire sur elle même, jusqu'à ce que la variable atteigne zéro. Comme cette instruction DJNZ nécessite plusieurs cycles d'horloge, des instructions NOP (qui font rien du tout sauf consommer un cycle d'horloge ), ont été ajoutées à sa suite pour ajuster au cycle près la durée de la temporisation.



    Plutôt que de répéter X fois la même séquence d'instructions, il est préférable de les regrouper sous une macro. Macro qui sera déclarée en tête de programme et appelée autant de fois que nécessaire dans le programme, exemple :

    SetColor   MACRO   Color,Delay   ; Déclaration de la macro et de ses deux paramètres
    LOCALLocLoop; Étiquette interne à la macro
    MOVW,RA; Lecture du port RA
    ANDW,#%1000; Effacement des 3 bits de couleur
    ORW,#Color; Positionnement des seuls bits impactés par la nouvelle couleur
    MOVRA,W; Émission de cette nouvelle couleur
    MOVCounter,#Delay; Initialisation du compteur
    LocLoopDJNZCounter,LocLoop
    NOP
    NOP
    ENDM

    Avec une temporisation fantaisiste de 100 choisie pour cet exemple, l'émission des 8 barres colorées pourra s'écrire plus simplement,  :

    Start   SetColor   White,100
    SetColorYellow,100
    SetColorCyan,100
    SetColorGreen,100
    SetColorMagenta,100
    SetColorRed,100
    SetColorBlue,100
    SetColorBlack,100

    Les intervalles de suppression correspondent en fait à l'émission d'aucun bit de couleur donc à l'émission de la couleur noire. Il n'est alors pas utile de dissocier l'émission de la dernière barre de celle du palier de suppression avant, elle et il peuvent être regroupés en une seule émission de la couleur noire avec augmentation de la temporisation en conséquence, la séquence devient alors :

    Start   SetColor   Black,30   ; Émission du palier de suppression arrière, durée 30
    SetColorWhite,100
    SetColorYellow,100
    SetColorCyan,100
    SetColorGreen,100
    SetColorMagenta,100
    SetColorRed,100
    SetColorBlue,100
    SetColorBlack,100+20; Palier de suppression avant accolé à dernière bande, durée 20



    Pour l'exemple, les délais passés à la macro étaient fantaisistes. Il va falloir maintenant utiliser les pas calculés dans le précédent post pour chaque fréquence de balayage et faire en sorte que la macro puisse s'en servir directement pour éviter à chaque fois des calculs fastidieux.

    Il est nécessaire de quantifier la durée de la macro "SetColor" en nombre de cycles :

    SetColor   MACRO   Color,Delay   
    LOCALLocLoop
    MOVW,RA; 1 cycle
    ANDW,#%1000; 1 cycle
    ORW,#Color; 1 cycle
    MOVRA,W; 1 cycle
    MOVCounter,#Delay; 2 cycles
    LocLoopDJNZCounter,LocLoop; 4 cycles sinon 2 en sortie de boucle
    ...
    ENDM

    Ce qui donne : 1 + 1 + 1 + 1 + 2 + (4 × (Delay-1)) + 2 cycles, ce qui se simplifie en : 4 × (Delay+1)

    Autrement dit, une unité du paramètre "Delay" équivaut actuellement à 4 cycles d'horloge. Si l'on veut qu'une unité de "Delay" corresponde à un pas ou cycle, il va falloir diviser le nombre de bouclettes par 4 moins une et rajouter de 1 à 3 "NOP" pour affiner la temporisation au plus près :

    SetColor   MACRO   Color,Delay   ; Déclaration de la macro et de ses deux paramètres
    LOCALLocLoop; Étiquette interne à la macro
    MOVW,RA; Lecture du port RA
    ANDW,#%1000; Effacement des 3 bits de couleur
    ORW,#Color; Positionnement des seuls bits impactés par la nouvelle couleur
    MOVRA,W; Émission de cette nouvelle couleur
    MOVCounter,#((Delay/4)-1); Initialisation du compteur de bouclettes
    LocLoopDJNZCounter,LocLoop
    REPTDelay//4; Affinage, répétition de NOP modulo 4
    NOP
    ENDR
    ENDM

    L'opérateur "/" effectue une division ayant un nombre entier comme résultat alors que l'opérateur "//" ou modulo permet de récupérer le reste de cette même division. Ainsi la macro peut calculer automatiquement le nombre de bouclettes adéquates et insérer l'appoint en instructions "NOP".



    Avec le nombre de pas calculés dans le post précédent, une ligne de la mire à barres colorées peut s'exprimer ainsi pour la fréquence de 15 kHz :

    Start   SetColor   Black,323   ; Émission du palier de suppression arrière, durée 323 cycles
    SetColorWhite,307
    SetColorYellow,307
    SetColorCyan,307
    SetColorGreen,307
    SetColorMagenta,307
    SetColorRed,307
    SetColorBlue,307
    SetColorBlack,307+161; Palier de suppression avant accolé à dernière bande, durée 161 cycles

    On peut même pousser le luxe en englobant cette série de macros dans une nouvelle macro à laquelle on ne fourni que les paramètres de durée des différents intervalles :

    ColorBars   MACRO   DelayBP,DelayBar, DelayFP   ; Déclaration de la macro et de ses trois paramètres
       SetColor   Black,DelayBP   ; Émission du palier de suppression arrière (BP as Back Porch)
    SetColorWhite,DelayBar
    SetColorYellow,DelayBar
    SetColorCyan,DelayBar
    SetColorGreen,DelayBar
    SetColorMagenta,DelayBar
    SetColorRed,DelayBar
    SetColorBlue,DelayBar
    SetColorBlack,DelayBar+DelayFP; Palier de suppression avant accolé à dernière bande (FP as Front Porch)
    ENDM

    Ainsi pour générer la même ligne en 15 kHz il suffira d'écrire (après avoir écrit toutes les déclarations nécessaires ) :

    Bars15   ColorBars   323,307,161   ; Émission d'une ligne à 15 kHz de la mire à barres colorées



    Aussi simple pour générer une ligne en 24 et en 31 kHz :

    Bars24   ColorBars   222,172,142; Émission d'une ligne à 24 kHz de la mire à barres colorées
    Bars31ColorBars87,122,17   ; Émission d'une ligne à 31 kHz de cette même mire.

    Bon maintenant il ne reste plus qu'à intégrer l'impulsion de synchronisation dans la ligne et à répéter les lignes autant de fois que nécessaire pour constituer la trame.
    « Modifié: Mercredi 30 Janvier 2013, 10:35:12 am par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #5 le: Vendredi 01 Février 2013, 11:35:36 am »
  • Un petit retour en arrière sur la macro "SetColor" ou plus exactement sur les deux lignes de code (en bleu) qui réalisent la temporisation :

    SetColor   MACRO   Color,Delay   ; Déclaration de la macro et de ses deux paramètres
    LOCALLocLoop; Étiquette interne à la macro
    MOVW,RA; Lecture du port RA
    ANDW,#%1000; Effacement des 3 bits de couleur
    ORW,#Color; Positionnement des seuls bits impactés par la nouvelle couleur
    MOVRA,W; Émission de cette nouvelle couleur
    MOVCounter,#((Delay/4)-1); Initialisation du compteur de bouclettes
    LocLoopDJNZCounter,LocLoop
    REPTDelay//4; Affinage, répétition de NOP modulo 4
    NOP
    ENDR
    ENDM

    La taille de la variable "Counter" étant d'un octet, elle ne peut servir à décompter que 256 bouclettes au maximum, la temporisation s'étage donc entre (1 + 1) × 4 = 8  et (1 + 25) × 4 = 1028 cycles d'horloge par sauts de 4 en 4.
    Ces 1028 cycles ou pas maximum ne seront pas suffisants dans le cas de la mire clignotante où toutes les lignes sont uniformes pendant un intervalle de temps aussi grand que 2456 pas dans le cas du 15 kHz.
    Il convient donc de réécrire cette macro et d'en profiter pour isoler les lignes de code de la temporisation dans une nouvelle macro spécifique afin d'éviter leur répétition intempestive dans le programme source.

    Tout d'abord les deux lignes (en bleu) peuvent être isolées dans une sous-macro indépendante :
      
    BasicDelay   MACRO   Value   ; Déclaration de la macro et de son paramètre
    LOCALLocLoop; Étiquette interne à la macro
    MOVLoopCounter,#Value; 2 cycles, initialisation du compteur de bouclettes
    LocLoopDJNZLoopCounter,LocLoop; 4 cycles sinon 2 en sortie de boucle
    ENDM

    Le nom de la variable "Counter" évolue en LoopCounter pour l'identifier immédiatement par rapport aux autres compteurs "LineCounter" et "FrameCounter" qui seront utilisés par la suite.
    La temporisation, en nombre de cycles, réalisée par cette macro de base est tout simplement égale à 4 fois la valeur paramétrée.

    La temporisation maximum réalisable par cette macro est donc de 1024 cycles d'horloge (256 × 4). Plutôt que de décompter, avec un deuxième compteur, le nombre de fois ou une telle macro sera utilisée, il est plus simple d'en accoler plusieurs à la suite surtout qu'un nombre raisonnable de trois sera nécessaire pour atteindre la temporisation de 2456 pas évoquée plus en avant.

    En choisissant une valeur maximum de 250 au lieu de 256, ce qui correspond au nombre bien bien plus pratique de 1000 cycles, la temporisation voulue pourra être ainsi exprimée :

          REPT   Value/250   ; Correspond à 250 × 4 soit 1000 cycles d'horloge
     BasicDelay250
    ENDR
    BasicDelayValue//250; Complémenté par le reste de la division par 250

    A fin d'éviter à l'assembleur de recalculer à chaque fois l'expression ((Delay/4)-1) on peut assigner cette expression à un symbole redéfinissable, ici "Loops", grâce à la directive "SET" :

    Loops   SET   (Delay/4)-1
    REPTLoops/250   ; Correspond à 250 × 4 soit 1000 cycles d'horloge
     BasicDelay250
    ENDR
    BasicDelayLoops//250; Complémenté par le reste de la division par 250

    Chaque boucle élémentaire consommant 4 cycles d'horloge, il faut rajouter l'affinage final à la nouvelle macro "Wait" qui va maintenant gérer les temporisations :

    Wait   MACRO   Delay   ; Déclaration de la macro et de son paramètre
    Loops   SET   (Delay/4)-1
    REPTLoops/250   ; Correspond à 250 × 4 soit 1000 cycles d'horloge
     BasicDelay250
    ENDR
    BasicDelayLoops//250; Complémenté par le reste de la division par 250
    REPTDelay//4; Affinage, répétition de NOP modulo 4
     NOP
    ENDR
    ENDM

    Ainsi la précédente macro "SetColor" peut maintenant s'écrire :

    SetColor   MACRO   Color,Delay   ; Déclaration de la macro et de ses deux paramètres
    MOVW,RA; 1 cycle, lecture du port RA
    ANDW,#%1000; 1 cycle, effacement des 3 bits de couleur
    ORW,#Color; 1 cycle, positionnement des seuls bits impactés par la nouvelle couleur
    MOVRA,W; 1 cycle, émission de cette nouvelle couleur
    WaitDelay; Temporisation, tient compte des 4 cycles absorbés par les instructions précédentes
    ENDM



    La nouvelle macro dédiée à la temporisation inclus dans son calcul de boucles un offset qui correspond aux 4 cycles des instructions l'ayant précédé. Ces instructions ayant permis de changer de couleur, voici une représentation explicitant l'impact de ce décalage sur l'affichage des barres colorées de la mire :



    La nouvelle couleur n'est émise qu'après exécution de l'instruction "MOV  RA,W", et comme le décalage de 4 cycles est systématique pour chaque nouvelle couleur, les durées sont toujours respectées au cycle près.
    Le traitement de la synchronisation horizontale devra de fait être calqué sur celui des barres colorées et assumer ce même décalage.



    • A l'extrême gauche la représentation de la fin de la dernière barre de la mire : la barre noire.
    • Ensuite débute l'enchaînement de 3 intervalles de temps communs à toutes les différentes mires :
      • Le palier de suppression avant, l'émission de la couleur noire est impérative pour la raison évoquée ci-dessus car la couleur précédente peut être différente.
      • L'impulsion de synchronisation, la couleur restant noire, inutile de l'émettre à nouveau. L'intervalle de 4 cycles qu'occupait cette opération est mis à profit pour émettre cette impulsion :
        • 3 cycles sont absorbés par une instruction qui n'exécute qu'un saut sur la suivante :
                JMP   $+1   ; Absorpsion de 3 cycles
          Le sigle "$" représentant l'adresse de l'instruction "JMP", $+1 représente donc celle de la suivante
        • La dernière est une manipulation de bit qui positionne le port associé à la synchronisation horizontale :
                SETB   SyncH   ; Emission de l'impulsion
          Ce port aura préalablement été déclaré en tête de programme :
             SyncH   EQU   RB.0   ; Synchronisation horizontale, port RB0, patte 10
          SyncVEQURB.1; Synchronisation verticale, port RB1, patte 11
      • Le palier de suppression arrière. Il efface l'impulsion de synchronisation horizontale après absorpsion de 3 cycles par une instruction "JMP".
              JMP   $+1   ; Absorpsion de 3 cycles
        CLRBSyncH; Effacement de l'impulsion
    • Et enfin à l'extrême droite la figuration du début de la première bande de la ligne suivante, la barre blanche.



    Avec la précédente macro ColorBars réécrite sans les paliers de suppression :

    ColorBars   MACRO   DelayBar   ; Déclaration de la macro et de son unique paramètre
    SetColorWhite,DelayBar; Première barre verticale
    SetColorYellow,DelayBar
    SetColorCyan,DelayBar
    SetColorGreen,DelayBar
    SetColorMagenta,DelayBar
    SetColorRed,DelayBar
    SetColorBlue,DelayBar
    SetColorBlack,DelayBar; La huitième barre est aussi la dernière
    ENDM

    Avec le nombre de pas calculés dans le premier post, la définition dans le post précédent d'une ligne de la mire à barres colorées peut être réexprimée ainsi pour la fréquence de 15 kHz :

                      ; Palier de suppression arrière (Back Porch)
    JMP$+1; Absorpsion de 3 cycles
    CLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Affichage des 8 barres colorées de la mire
    ColorBars307; Affichage de la mire, chaque barre occupe un intervalle de 307 cycles
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161; Suppression de la dernière couleur par forçage du noir, durée du palier 161 cycles
    ; Impulsion de synchronisation horizontale
    JMP$+1; Absorpsion de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes

    En réordonnant les instructions afin d'utiliser un des sauts absorbateur pour assurer indéfiniment le rebouclage de la séquence :

                      ; Palier de suppression arrière (Back Porch), suite
    LineLoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Affichage des 8 barres colorées de la mire
    ColorBars307; Affichage de la mire, chaque barre occupe un intervalle de 307 cycles
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161; Suppression de la dernière couleur par forçage du noir, durée du palier 161 cycles
    ; Impulsion de synchronisation horizontale
    JMP$+1; Absorpsion de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPLineLoop; Rebouclage avec absorpsion de 3 cycles

    Les durées des différents intervalles d'une ligne sont ainsi respectés au cycle près, la prochaine étape consistera à compter les lignes pour déterminer les différents intervalles d'une trame.



    Le câblage prévu pour raccorder les synchronisations sur l'embase HD-15 en profitant des deux derniers buffers dans le LS367 :





    Après assemblage du code source, simulation avec le simulateur SXSim pour vérification des temporisations et enfin programmation d'un SX28AC avec le programmateur Fluffy-2, voici les différents signaux échantillonnés à 20 MHz par le Scanalogic 2 pour une fréquence ligne de 15 kHz :
    • CH1/trace bleue pour le signal du bleu.
    • CH2/trace jaune pour la synchronisation horizontale.
    • CH3/trace rouge pour le signal du rouge.
    • CH4/trace verte pour le signal du vert.
    A comparer avec les chronogrammes du dessin inclus en tête du post précédent.





    Par contre quand ces mêmes signaux sont visualisés à l'oscilloscope, ils sont beaucoup moins lisses, le palier correspondant au niveau logique haut n'est pas exempt de "glitches"

    Par exemple pour le signal du bleu :



    Avec une résistance de 4,7 kΩ entre la masse et la sortie concernée du LS367 pour soutirer un peu de courant au transistor qui assure le niveau haut, les "glitches" disparaissent et le palier redevient plat, quoique le niveau correspondant se soit affaissé de quelques dixièmes de volt.



    « Modifié: Mardi 05 Février 2013, 18:12:39 pm par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne pn_jeux

    • Addict
    • *
    • Messages: 329
    • Localisation: Cheratte (Prov. Liège)
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #6 le: Vendredi 01 Février 2013, 12:13:54 pm »
  • Bonjour, cela me rappelle que j'avais réalisé un petit programme de mires sur Atari st, il est vrai que ces microcontrôleurs Scenix ont une puissance de calcul phénoménale, certains ont réussi à programmer des jeux vidéo. Fameux travail, en tout cas... ^-^

    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #7 le: Vendredi 01 Février 2013, 13:16:23 pm »
  • il est vrai que ces microcontrôleurs Scenix ont une puissance de calcul phénoménale, certains ont réussi à programmer des jeux vidéo.


    Non seulement le µC SX exécute le programme du jeu en affichant les scores, mais il arrive à générer la sous-porteuse NTSC/PAL avec le reste de cycles machine disponibles car il délivre en sortie un signal couleur en vidéo composite acceptable directement par une TV !
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne Shuff

    • Accro
    • *
    • Messages: 207
    • Localisation: Rouen
      • Voir le profil
      • Emurom.net
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #8 le: Vendredi 01 Février 2013, 15:27:06 pm »
  • Très instructif et détaillé ce topic.
    Merci de partager ce travail avec nous gc339  <:)

    Hors ligne CkurcK

    • Grand Pilier
    • *
    • Messages: 865
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #9 le: Samedi 02 Février 2013, 00:20:05 am »
  • Wouaw merci pour ce partage !

    C'est pour ça que j'aime Gamo !!!  :-)=

    Hors ligne nc333

    • VIP
    • *
    • Messages: 1653
    • Localisation: Savoie - 73610
    • Jeune padawan de l'arcade
      • Voir le profil
      • Nc333 - Bordel diverse et avarié
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #10 le: Mercredi 06 Février 2013, 20:53:47 pm »
  • Je propose quelque amélioration:
    _afficher le bord du quadrillage en une autre couleur, effectivement quand l'écrans est très déréglé on ne peut savoir si l'image est décentré de un ou deux carreau

    _Garder une page blanche en plus, peut s’avérer utile pour mètre en évidence le marquage du tube ou pour réglé la luminosité de la THT

    _ Faire un dégradé de chaque couleur, pour régler les cut-offs

    _Mettre le montage sur batterie  :)

    Je suis toujours impressionné par le niveau de tes réalisation.
    "Bon, j'ai pas mal réfléchi. Quand la vie vous fait trébucher, ça ne suffit pas de se relever. Il faut lui péter les rotules, à cette grognasse ! Œil pour œil, dent pour dent ! « Essaie un peu de te relever, maintenant, traînée ! »" Caves Johnson, 1980

    La présentation c'est ICI :)

    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #11 le: Jeudi 07 Février 2013, 14:38:19 pm »
  • Une trame ne comporte pas que des lignes dont le contenu est représentatif, elle est aussi composée de lignes inertes encadrant celles consacrées à la synchronisation verticale dont le contenu est forcé au niveau du noir. Le bloc de lignes représentant une période quelconque de la trame, pourra être redéfini ainsi (pour une mire à 15 kHz ):

                      ; Palier de suppression arrière (Back Porch), suite
    LineLoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Période d'affichage
    IFDisplayPatten=1
     ColorBars307; Affichage de la mire, chaque barre occupe un intervalle de 307 cycles
    ELSE
     SetColorBlack,2456; Niveau du noir imposé pendant 2456 cycles
    ENDIF
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161; Suppression de la dernière couleur par forçage du noir, durée du palier 161 cycles
    ; Impulsion de synchronisation horizontale
    JMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPLineLoop; Rebouclage avec absorption de 3 cycles

    Le problème vient du fait que ce bloc boucle indéfiniment sur lui-même sans jamais enchaîner sur un autre, il est donc nécessaire de lui insérer un comptage pour que le contrôle échoie au bloc suivant une fois le bon nombre de lignes déroulées atteint.
    Mais avant de réaliser cette inclusion, il est nécessaire de différencier chaque bloc de lignes par une étiquette globale. Les étiquettes suivantes seront déclarées locales à ce même bloc en les préfixant par deux points verticaux ":" ce qui devrait permettre de réutiliser localement les mêmes noms sans conflit dans les autres blocs :

    BlockDraft     EQU     $     ; Étiquette globale en entête du bloc d'instructions
    ; Palier de suppression arrière (Back Porch), suite
    :Loop  CLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Période d'affichage
    IFDisplayPatten=1
     ColorBars307; Affichage de la mire, chaque barre occupe un intervalle de 307 cycles
    ELSE
     SetColorBlack,2456; Niveau du noir imposé pendant 2456 cycles
    ENDIF
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161; Suppression de la dernière couleur par forçage du noir, durée du palier 161 cycles
    ; Impulsion de synchronisation horizontale
    :Start  JMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMP:Loop  ; Rebouclage local avec absorption de 3 cycles

    Ainsi les deux étiquettes "Loop" et ":Start" seront locales à ce bloc mais pourront être connues des autres comme étiquettes globales si on les préfixe par celle du bloc d'instructions auquel elles appartiennent, exemple : "BlockDraft:Start"
    L'emplacement le plus judicieux pour insérer le comptage se situe à la fin du palier avant de la suppression ligne auquel il devra emprunter quelques cycles machine.
    Deux cas de figure après décomptage d'une ligne :
    • LineCounter ≠ 0, l'enchaînement est repris dans le même bloc à partir de son étiquette ":Start"
    • LineCounter = 0, le compteur est rechargé avec le nombre de lignes de la période suivante et l'enchaînement est transféré sur l'étiquette ":Start" du bloc suivant.



    Mais il y a échec lors de l'assemblage car les étiquettes locales ne le sont qu'à la suite d'instructions précédée par une étiquette globale et le drame vient du fait que les macros sont aussi considérées comme des étiquettes globales, ainsi les étiquettes ":Loop" et "Start" ne sont plus locales à la même suite d'instructions puisque celle-ci à été fractionnée par les macros invoquées entre-temps.
    L'astuce trouvée, quoique pas très orthodoxe, a été de redéfinir l'étiquette globale après invocation des macros à l'aide d'une seconde directive "SET" :

    BlockDraft     SET     $     ; Étiquette globale en entête du bloc d'instructions
    ; Palier de suppression arrière (Back Porch), suite
    :Loop  CLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Période d'affichage
    IFDisplayPatten=1
     ColorBars307; Affichage de la mire, chaque barre occupe un intervalle de 307 cycles
    ELSE
     SetColorBlack,2456; Niveau du noir imposé pendant 2456 cycles
    ENDIF
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161; Suppression de la dernière couleur par forçage du noir, durée du palier 161 cycles
    BlockDraft  SET  $  ; Étiquette globale redéfinie sur cette nouvelle adresse
    ; Impulsion de synchronisation horizontale
    :Start  JMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPBlockDraft:Loop  ; Rebouclage avec absorption de 3 cycles


    Ainsi les deux étiquettes locales impliquées semblent appartenir en première lecture au même bloc d'instructions alors que l'assembleur fait bien la distinction et assemble le code sans générer une quelconque erreur.



    Étant donné que le compteur devra pouvoir compter jusqu'à 480 lignes avec le 31 kHZ, un seul octet ne sera pas suffisant, il faut donc le prévoir sur un mot de 2 octets :

          ORG   8   ; Début de mémoire utilisable
    LoopCounterDS1; Compteur de boucles
    LineCounterDS2; Compteur de lignes
    FrameCounterDS1; Compteur de Trames

    En fait le compteur ne comptera pas les lignes mais les décomptera, leur nombre ayant été préalablement initialisé par le bloc précédent avant de transférer l'exécution dans celui-ci.
    La suite d'instructions suivantes gérant ce comptage est destinée à être incluse dans n'importe quel bloc de la trame, en fin du palier de suppression avant comme cela a été projeté :

          DJNZ   LineCounter,Label1   ; -1 sur octet de poids faible
    TESTLineCounter+1; Test sur l'octet de poids fort
    JZLabel2
    DECLineCounter+1; -1 sur octet de poids fort
    SKIP; 6 cycles déjà consommés, 8 à absorber pour atteindre l'adresse :Start
    Label1JMP$+2; 4 cycles déjà consommés, 10 à absorber pour atteindre l'adesse :Start
    SKIP
    JMP$+1
    NOP
    JMPBlock:Start; Étiquette locale du bloc où cette suite d'instruction a été insérée
    Label2MOVLineCounter,#(Value//256); Chargement du compteur, octet de poids faible
    MOVLineCounter+1,#(Value/256); Idem, octet de poids fort
    JMPNextBlock:Start; Étiquette locale du bloc suivant où l'exécution doit être transférée

    Le nombre de cycles le plus grand de cette suite d'instructions est celui du traitement où le compteur a atteint zéro et il est dans ce cas égal à 14. Aux autres cas de figure doivent correspondre le même temps d'exécution, c'est pour cela qu'ils ont été ajustés au cycle près par l'insertion d'instructions inertes comme NOP (1 cycle ), SKIP (2 cycles ) et JMP (3 cycles )

    Cette suite d'instructions testant le compteur de lignes peut-être transformé en macro invoquable par les différents blocs dont une trame est constituée :

    NextLine   MACRO   CurrentBlock,NextBlock, NewLineNumber   
    LOCALLabel1,Label2; Déclaration des étiquettes privées
    DJNZLineCounter,Label1; -1 sur octet de poids faible
    TESTLineCounter+1; Test sur l'octet de poids fort
    JZLabel2
    DECLineCounter+1; -1 sur octet de poids fort
    SKIP; 6 cycles déjà consommés, 8 à absorber pour atteindre l'adresse :Start
    Label1JMP$+2; 4 cycles déjà consommés, 10 à absorber pour atteindre l'adresse :Start
    SKIP
    JMP$+1
    NOP
    JMPCurrentBlock??:Start; Étiquette locale du bloc où cette suite d'instruction a été insérée
    Label2MOVLineCounter,#(NewLineNumber//256); Chargement du compteur, octet de poids faible
    MOVLineCounter+1,#(NewLineNumber/256); Idem, octet de poids fort
    JMPNextBlock??:Start; Étiquette locale du bloc suivant où l'exécution doit être transférée
    ENDM

    L'opérateur "??" permet de concaténer le nom de l'étiquette globale passée en tant que paramètre à celui de l'étiquette locale accolée à la suite en temps que texte.



    On peut maintenant juxtaposer les différents blocs pour écrire le code d'une trame de la mire à barre colorées.
    Le nombre de lignes de chaque bloc est issu du timing des signaux à 15 kHz joint au premier post de ce wip :

    FrameStart   JMP   LeadingField:Start

    ;------------------------------------------ Blanking avant ----------------------------------------
     
    LeadingField   SET   $
       ; Palier de suppression arrière (Back Porch), suite
    :LoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Blanking des lignes précédant l'impulsion trame
    SetColorBlack,2456; Contenu des lignes forcé au niveau du noir pendant le blanking trame
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161-14; Palier forcé au niveau du noir, prise en compte des 14 cycles du décomptage
    LeadingFieldSET$; Décomptage des lignes du bloc en fin du palier (14 cycles)
    NextLineLeadingField,SyncField,3; Durée de 3 lignes pour l'impulsion de synchronisation verticale
    ; Impulsion de synchronisation horizontale
    :StartJMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPLeadingField:Loop; Rebouclage avec absorption de 3 cycles

    ;------------------------------ Impulsion de synchronisation trame --------------------------------
     
    SyncField   SET   $
       ; Palier de suppression arrière (Back Porch), suite
    :LoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Blanking des lignes pendant l'impulsion de synchronisation trame
    SetColorBlack,2456; Contenu des lignes forcé au niveau du noir pendant l'impulsion de synchronisation trame
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161-14; Palier forcé au niveau du noir, prise en compte des 14 cycles du décomptage
    SyncFieldSET$; Décomptage des lignes du bloc en fin du palier (14 cycles)
    NextLineSyncField,LaggingField,23; Durée de 23 lignes pour le blanking arrière
    ; Impulsion de synchronisation horizontale
    :StartJMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPSyncField:Loop; Rebouclage avec absorption de 3 cycles

    ;----------------------------------------- Blanking arrière ---------------------------------------
     
    LaggingField   SET   $
       ; Palier de suppression arrière (Back Porch), suite
    :LoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Blanking des lignes à la suite de l'impulsion trame
    SetColorBlack,2456; Contenu des lignes forcé au niveau du noir pendant le blanking trame
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161-14; Palier forcé au niveau du noir, prise en compte des 14 cycles du décomptage
    LaggingFieldSET$; Décomptage des lignes du bloc en fin du palier (14 cycles)
    NextLineLaggingField,PatternField,224; Durée de 224 lignes pour afficher la mire à barres colorées
    ; Impulsion de synchronisation horizontale
    :StartJMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPLaggingField:Loop; Rebouclage avec absorption de 3 cycles

    ;---------------------------------------- Affichage de la mire --------------------------------------
     
    PatternField   SET   $
       ; Palier de suppression arrière (Back Porch), suite
    :LoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Affichage des 8 barres colorées de la mire
    ColorBars307; Affichage de la mire, chaque barre occupe un intervalle de 307 cycles
    ; Palier de suppression avant (Front Porch)
    SetColorBlack,161-14; Palier forcé au niveau du noir, prise en compte des 14 cycles du décomptage
    LaggingFieldSET$; Décomptage des lignes du bloc en fin du palier (14 cycles)
    NextLinePatternField,LeadingField,13; Durée de 13 lignes pour le blanking avant
    ; Impulsion de synchronisation horizontale
    :StartJMP$+1; Absorption de 3 cycles
    SETBSyncH; Émission de l'impulsion
    Wait238; Durée de l'impulsion, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPPatternField:Loop; Rebouclage avec absorption de 3 cycles

    D'emblée on se rend compte que le palier arrière d'une ligne peut être confondu avec son contenu car il sont tous les deux forcés au niveau du noir pendant les périodes de suppression trame ou blanking : lignes écrites en bleu.
    A ce propos, le simulateur SXSim a permis de faire ressortir un problème au niveau de l'assembleur, l'expression "161-14" passée comme paramètre à la macro SetColor n'est pas évaluée par celle-ci, mais par la macro fille "Wait" qui applique la précédence des opérateurs dans ses calculs, ce qui donne des résultats inattendus. La solution est soit d'englober l'expression par des parenthèses soit de modifier cette macro "Wait" pour que son paramètre "Delay" soit entouré de ces parenthèses à chaque fois qu'il doit être évalué.
    Cette dernière solution est de loin la préférable :

    Wait   MACRO   Delay   ; Déclaration de la macro et de son paramètre
    LoopsSET( (Delay) /4)-1
    Cycles  SET (Delay)//4  
    REPTLoops/250; Correspond à 250 × 4 soit 1000 cycles d'horloge
     BasicDelay250
    ENDR
    BasicDelayLoops//250; Complété par le reste de la division par 250
    IF  Cycles=3  ; Affinage
     JMP  $+1  ; Absorbe 3 cycles en une seule instruction
    ELSE  
     REPTCycles  ; Répétition de NOP modulo 4
       NOP
     ENDR
    ENDIF  
    ENDM

    Conjointement à cette correction, la macro a été modifiée pour économiser de la mémoire programme. Un test est maintenant effectué sur le nombre de cycles à ajuster et s'il est égal à 3, la répétition d'instructions "NOP" est remplacée par une seule instruction "JMP $+1" qui absorbe à elle seule 3 cycles à la fois.



    Maintenant que la trame est constituée et qu'elle boucle indéfiniment sur elle-même, il reste plus qu'à gérer l'impulsion de synchronisation verticale sur le port RB1.
    Pour que début et la fin de cette impulsion de synchronisation trame soit strictement synchrone avec celle de la synchronisation ligne, l'émission de cette dernière doit être modifiée pour que les deux changent d'état simultanément tout en respectant le temps d'exécution de 4 cycles précédemment évoqué : surlignage marron  .

    ;------------------------------ Impulsion de synchronisation trame --------------------------------
     
    SyncField   SET   $
       ; Palier de suppression arrière (Back Porch), suite
    :LoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Blanking des lignes pendant la synchronisation trame
    SetColor Black,2456+161-14  ; Contenu + palier avant forcés au niveau du noir pendant cette période. Moins les 14 cycles du décomptage
    SyncFieldSET$; Décomptage des lignes du bloc en fin du palier (14 cycles)
    NextLineSyncField,LaggingField,23; Durée de 23 lignes pour le blanking arrière
    ; Impulsion de synchronisation horizontale
    :StartMOV  W,RB  ; Lecture du port RB, la manipulation de bits impossible sur W est réalisée sur son emplacement mémoire WREG
    SETB  WREG.0  ; Positionnement du bit correspondant à la synchronisation horizontale
    SETB  WREG.1  ; Positionnement  du bit correspondant à la synchronisation verticale
    MOV  RB,W  ; Émission de ce nouvel état
    Wait238; Durée de l'impulsion ligne, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPSyncField:Loop; Rebouclage avec absorption de 3 cycles

    ;----------------------------------------- Blanking arrière ---------------------------------------
     
    LaggingField   SET   $
       ; Palier de suppression arrière (Back Porch), suite
    :LoopCLRBSyncH; Effacement de l'impulsion de synchronisation Horizontale
    Wait323; 323 cycles pour le palier arrière, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Blanking des lignes à la suite de la synchronisation trame
    SetColor Black,2456+161-14  ; Contenu + palier avant forcés au niveau du noir pendant cette période. Moins les 14 cycles du décomptage
    LaggingFieldSET$; Décomptage des lignes du bloc en fin du palier (14 cycles)
    NextLineLaggingField,PatternField,224; Durée de 224 lignes pour afficher la mire à barres colorées
    ; Impulsion de synchronisation horizontale
    :StartMOV  W,RB  ; Lecture du port RB, la manipulation de bits impossible sur W est réalisée sur son emplacement mémoire WREG
    SETB  WREG.0  ; Positionnement du bit correspondant à la synchronisation horizontale
    CLRB  WREG.1  ; Effacement  du bit correspondant à la synchronisation verticale
    MOV  RB,W  ; Émission de ce nouvel état
    Wait238; Durée de l'impulsion ligne, tient compte des 4 cycles absorbés par les instructions précédentes
    ; Palier de suppression arrière (Back Porch)
    JMPLaggingField:Loop; Rebouclage avec absorption de 3 cycles

    La manipulation de bits, ceux correspondant aux synchronisations, est impossible sur l'accumulateur W, cependant ce registre peut être mappé en mémoire à la place d'un autre qui réside à l'adresse $01.
    Deux conditions sont alors requises :
    • Avoir positionné le pseudo fusible OPTIONX qui sera programmé en même temps que le code dans le microcontrôleur SX28. Sinon le bit "RTW" du registre "OPTION" restera positionné à 1.
      Ceci s'effectue dans le texte source à l'aide de la directive "DEVICE  OPTIONX"
    • Que le bit "RTW" dans le registre "OPTION" soit à 0.
      Tous les bits ayant été positionnés à 1 suite au reset, il faut l'avoir préalablement effacé avec l'instruction "MOV  !option,#%0111111" lors de la séquence d'initialisation sinon on accède au compteur/temporisateur RTCC à la place.
    L'accumulateur W est alors accessible en temps que registre mémoire "WREG" et ses bits peuvent être alors manipulés aisément.



    Après nouvel assemblage du code source et programmation d'un SX28AC avec le programmateur Fluffy-2, voici les différents signaux échantillonnés à 10 MHz par le Scanalogic 2 pour une fréquence ligne de 15 kHz :
    CH1/trace bleue pour la synchronisation horizontale.
    CH2/trace jaune pour la synchronisation verticale.


    Le temps mesuré entre deux impulsions de synchronisation trame avec la fonction "Quick time selection" est de 17,716 ms, le "Recommended Signal Timing Chart" inséré dans le premier post de ce wip donnait 16,715 ms, c'est tout bon compte tenu de toutes les imprécisions.

    Le détail de l'impulsion trame, elle dure bien les trois lignes prévues :



    Maintenant reste à intégrer la lecture des dip-switches pour pouvoir choisir la fréquence ligne de la mire...
    « Modifié: Mardi 12 Février 2013, 09:08:17 am par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #12 le: Lundi 11 Février 2013, 23:41:52 pm »
  • Je propose quelques améliorations :
    _afficher le bord du quadrillage en une autre couleur, effectivement quand l'écran est très déréglé on ne peut savoir si l'image est décentrée de un ou deux carreaux

    Oui, c'est facilement faisable dans le cas de la mire à quadrillage. Mais je pencherais plus pour un trait de cadre plus épais ou constitué d'un trait double.

    _Garder une page blanche en plus, peut s’avérer utile pour mettre en évidence le marquage du tube ou pour régler la luminosité de la THT

    Le marquage du cathoscope se voit plutôt quand il est éteint, la seule utilité que pourrait avoir une image uniformément blanche concerne plutôt le contrôle de l'efficacité de la démagnétisation

    _ Faire un dégradé de chaque couleur, pour régler les cut-offs

    Oui, j'ai déjà songé à inclure ce genre de mire :


    Photo postée à l'origine par kaneda56 sur Néo-Arcadia

    Cette mire nécessite 3 convertisseurs digital/analogique, un par couleur primaire, ce qui la complexifie. Mais pour l'instant ce n'est pas la priorité car j'ai surtout besoin d'un générateur simplifié.
    Mais j'ai prévu d'utiliser les 8 ports RC0 à RC7 qui restent disponibles et de réaffecter les 4 ports RA0 à RA3 à cet effet. Cela fera 12 ports au total pour piloter 3 réseaux R2-R avec 16 niveaux par couleur, juste ce qu'il faut pour obtenir la mire de dégradés comme celle de la photo.

    _Mettre le montage sur batterie
    Qui dit batteries, dit chargeur. Et c'est encore une complication pour un générateur vidéo qui se veut le plus simple possible avec un minimum de composants.

    Néanmoins, cette dernière proposition m'a fait réaliser qu'il vaudrait mieux que j'inclus le générateur dans un boîtier qui le protège.

    Un boîtier Teko de récupération va vivre une nouvelle vie, le circuit imprimé d'origine a été conservé car il incluait une petite alimentation secteur et aussi parce qu'il facilitait la fixation de la plaquette pré-percée au-dessus avec uniquement des entretoises de 15 mm. Néanmoins une découpe a été effectuée dans ce circuit, juste en dessous de la plaque pré-percée, pour laisser le champ libre aux broches des supports à wrapper.


    La découpe dans le circuit imprimé d'origine.
    La plaque pré-percée vue coté mini-wrapping avec la fixation de l'embase HD-15 ainsi que celle du bloc de mini-switches qui permettront de choisir la mire.



    La plaque prépercée en place sur ses entretoises.
    A gauche le bloc de mini-switches, au centre l'embase vidéo HD-15 et à droite celle du secteur 220 VAC, il/elles sont tous accessibles sur le même face du boîtier.


    La mire à barres colorée sur un Hantarex MTC9000, le commutateur SW4 du châssis a du être changé de position car la mire délivre des impulsions de synchronisation positives.
    « Modifié: Mardi 12 Février 2013, 00:27:15 am par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #13 le: Lundi 18 Février 2013, 17:07:38 pm »
  • Le timing des signaux à 15 kHz tel qu'il est donné à la page I-5 du "Service Manual" du moniteur MS-2931 :



    Et les durées retenues pour le générateur de mire, en nombre de pas de 20 ns :

    Timing ligne 15 kHz:   Timing Trame associé :
    • 161 pas ou µ-cycles pour le palier de suppression avant.
    • 238 pas pour l'impulsion de synchronisation horizontale.
    • 323 pas pour le palier de suppression arrière.
    • 2456 pas pour le contenu à afficher.
    • 13 lignes pour le champ de suppression avant.
    • 3 lignes pour l'impulsion de synchronisation verticale.
    • 23 lignes pour le champ de suppression arrière.
    • 224 lignes à afficher (au lieu de 381 ).

    Rien à redire en ce qui concerne la trame, le nombre de 224 lignes affichées est divisible par 8 (28 × 8 ) et convient donc parfaitement.




    Dans le timing trame des signaux à 24 kHz (moitié supérieure de la page I-6 du "Service Manual" du moniteur MS-2931 ), le nombre de lignes constituant l'image est égal à 381, nombre impair indivisible par 8 :



    Par contre dans le même timing à 24 kHz donné page 15/21 dans le "Service Manual" du moniteur du moniteur Nanao MS9-29SU le nombre de lignes affichées est de 384, nombre beaucoup plus pertinant puisque divisible par 8 (48 × 8 ).



    A durée de ligne égale (41 µs ) et durée de trame identique (17,384 ms ou 424 lignes ) ce nombre de lignes affichées supérieur est effectué au détriment du champ de suppression arrière qui de 28 lignes rétrograde à 25 lignes, toutes les autres durées élémentaires de la trame restant inchangées.

    Ce nombre de 384 lignes affichées par trame, est celui qui sera donc retenu pour les timings des signaux à 24 kHz que la mire la mire devra générer, ainsi :
    Timing ligne 24 kHz :   Timing Trame correspondant :
    • 142 pas ou µ-cycles pour le palier de suppression avant.
    • 150 pas pour l'impulsion de synchronisation horizontale.
    • 222 pas pour le palier de suppression arrière.
    • 1536 pas pour le contenu à afficher.
    • 11 lignes pour le champ de suppression avant.
    • 4 lignes pour l'impulsion de synchronisation verticale.
    • 25 lignes (au lieu de 28 ) pour le champ de suppression arrière.
    • 384 lignes à afficher (au lieu de 381 ).




    Par contre il y a un souci avec les timings des signaux à 31 kHz ou plus exactement à 31,67 kHz, ceux déjà évoqués et qui sont donnés à la page I-6 du "Service Manual" du moniteur MS-2931 :



    En effet, le palier de suppression avant de 0,33 µs calculé puis arrondi à 17 pas est trop court par rapport aux 14 cycles absorbés par la macro de comptage de lignes auxquels il faut encore ajouter 4 cycles supplémentaires pour l'émission de l'impulsion ligne.
    De plus le nombre de 477 lignes affichées dans une trame est impair, ce qui le disqualifie d'entrée.

    Il y a bien les timings à 31,69kHz donnés page 1-10 dans le "Service Manual" du moniteur Nanao MS2934 mais ils sont inexploitables car les chiffres sont illisibles :



    Heureusement, dans cette même notice, un tableau page 2-6 énumère toutes les informations qui étaient illisibles :



    Il reste donc 31,55 - (3,04 + 3,22 + 23,70) soit 1,59 µs pour le palier de suppression avant, ce qui en arrondissant correspond à 80 pas ou µ-cycles, ce qui est beaucoup plus confortable que les 17 pas extrapolés du timing précédent. Non seulement, le nombre de lignes affichées par trame est divisible par 8 (80 × 8 ), mais il correspond à celui du standard VGA.

    Ce sont aussi les mêmes timings, à 10 ns près en ce qui concerne la ligne, qui sont donnés page 5 dans le "Service Manual" du moniteur Sanwa 29E31S, ce qui les rend encore plus plausibles :



    Même avec les données du dernier graphique qui sont toutes des nombres pairs, il va falloir procéder à un ajustage car le nombre de 1185 pas (23700 ÷ 20 ) alloués à la période affichée dans chaque ligne n'est pas divisible par 8. Le nombre le plus proche étant 1184 (148 × 8 ), le palier de suppression qui est le plus court des 4 autres intervalles de temps, se doit d'être gratifié d'un pas supplémentaire pour compenser, on a donc :
    Timing ligne 31 kHz :   Timing Trame correspondant :
    • 81 pas ou µ-cycles pour le palier de suppression avant (au lieu des 17 précédents ).
    • 152 pas  pour l'impulsion de synchronisation horizontale.
    • 161 pas pour le palier de suppression arrière.
    • 1184 pas pour le contenu à afficher.
    • 14 lignes pour le champ de suppression avant.
    • 3 lignes pour l'impulsion de synchronisation verticale.
    • 33 lignes pour le champ de suppression arrière.
    • 480 lignes à afficher (au lieu des 477 précédentes ).




    Le câblage des dip-switches :



    Le bloc de dip-switches est raccordé directement sur les entrées RB4 à RB7 qu'ils connectent à la masse quand le switch correspondant est positionné sur "ON". Ainsi pour que l'entrée soit lue à l'état "1" quand son switch associé est positionné sur "OFF", il faut avoir préalablement validé les résistances de "pull-up" internes au micro-contrôleur. Il n'est pas nécessaire de valider ces résistances en permanence si l'on veut faire de petites économie de consommation, il suffit de les valider quelques cycles avant la lecture pour qu'elle soit fiable et de les inhiber immédiatement après.

    ;------------------------ INITIALIZATION ROUTINE -----------------------

       ORG   8
    Initializemovra,#%0000; Set port A low
    movrb,#%11111111; Set port B high
    movrc,#%11111111; Set port C high
    ; Pull-Up Resistor Configuration
    modePLP; Allow Pull-Up Resistor configuration
    mov!ra,#%1111; Set port A, bit 0-3 to normal
    mov!rb,#%00001111; Set port B bits 4-7 with pull-up resistors
    mov!rc,#%11111111; Set port C bits 0-7 to normal
    ; Port Direction Configuration
    modeTRIS; Allow Direction configuration
    mov!ra,#%0000; Set port A bits 0-3 to output
    mov!rb,#%11110000; Set port B bits 0-3 to output, 4-7 to input
    mov!rc,#%11111111; Set port C bits 0-7 to input

    Les registres notifiés !RA, !RB et !RC (avec le point d'exclamation ) ne sont pas des registres mais des points d'accès au bloc de registres qui contrôlent les ports RA, RB et RC. Il est nécessaire de définir préalablement le registre que l'on veut atteindre dans le bloc en écrivant sa sous-adresse dans le registre "MODE" commun à tous grâce à l'instruction du même nom.




    Maintenant que les paramètres des signaux à 15, 24 et 31 kHz ont été retouchés, que les dip-switches sont câblés, il ne reste plus qu'à écrire et tester le bout de programme qui permettra de choisir la bonne fréquence de la mire à barre colorées à la mise sous tension du générateur.
    Plus tard cette lecture des dip-switches pourra être effectuée à chaque trame ou toutes les X trames afin de pouvoir changer de mire et de fréquence au fil de l'eau sans avoir à réinitialiser le microcontrôleur à chaque changement.
    « Modifié: Samedi 08 Juin 2013, 16:36:40 pm par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne gc339

    • Beta Testeur
    • *
    • Messages: 2224
    • Localisation: Lyon
      • Voir le profil
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #14 le: Vendredi 07 Juin 2013, 15:53:36 pm »
  • Maintenant que les paramètres des signaux à 15, 24 et 31 kHz ont été retouchés, que les dip-switches sont câblés, il ne reste plus qu'à écrire et tester le bout de programme qui permettra de choisir la bonne fréquence de la mire à barre colorées à la mise sous tension du générateur.
    Plus tard cette lecture des dip-switches pourra être effectuée à chaque trame ou toutes les X trames afin de pouvoir changer de mire et de fréquence au fil de l'eau sans avoir à réinitialiser le microcontrôleur à chaque changement.

    Comme la mémoire programme du µC est paginée, 4 pages de 512 octets, et que le code du générateur dépasse allègrement cette limitation de page, il va falloir gérer la pagination de cette mémoire programme.
    Le plus simple est donc de réserver la page 0 aux initialisations et aux tests qui seront effectués dans la boucle principale et d'affecter chacune des trois pages restantes à l'exécution des boucles locales propres à chaque fréquence ligne :
    • Chaque boucle locale génèrera les mires pour une fréquence ligne donnée, ainsi les pages 1, 2 et 3 hébergeront respectivement les boucles locales pour les fréquences 15, 24 et 31 kHz.
    • L'exécution sera transférée en fin de chaque trame à la boucle principale qui lira alors les micro-switches.
    • Le contrôle passera de la boucle principale à la boucle locale désignée par ces micro-switches. S'il sont inchangés, le déroulement reprendra dans la même boucle locale là où il a été dérouté.
    Ainsi les micro-switches seront lus périodiquement et la fréquence ligne de la mire pourra être modifiée au fil de l'eau sans avoir à reseter le µC ou à couper son alimentation.



    Edition du 25/09/2015 : 1536 est la valeur correcte pour le 24 kHz.

    Rappel des timings choisis :

    Line
    Frequ.

    (kHz)
       |
    |
    |
       Front
    Porch

    (µcycles)
       Horiz.
    Synch.

    (µcycles)
       Back
    Porch

    (cycles)
       Display

    (µcycles)
       |
    |
    |
       Leading
    Blank

    (lines)
       Vert.
    Synch.

    (lines)
       Lagging
    Blank

    (lines)
       Pattern

    (lines)
    15 | 161 238 323 2456   | 13 3 23 224
    24 | 142 150 222 13361536   | 11 4 25 384
    31 | 81 152 161 1184   | 14 3 33 480



    Les déclarations en tête du programme :

    Citer

    ;-------------------------- DEVICE DIRECTIVES --------------------------
                                                                                                    
    IFDEF__SASM;SASM Directives
    DEVICESX28AC, OSCHS3, TURBO, BOROFF, SYNC, OPTIONX, CARRYX
    IRC_CALIRC_SLOW
    ELSE; Parallax Assembler Directives
    DEVICESX28AC, OSCXT2, TURBO, BOROFF, SYNC
    ENDIF
    ID"PATGEN"
    RESETInitialize; Reset vector

    ;------------------------------- EQUATES -------------------------------
                                                                                                    
    SyncHEQUrb.0; Synchro Horizontale sur RB0
    SyncVEQUrb.1; Synchro Verticale sur RB1
    BlackEQU%0000
    BlueEQU%0001; Bit 2°
    RedEQU%0010; Bit 2¹
    GreenEQU%0100; Bit 2²
    CyanEQUGreen + Blue
    MagentaEQURed + Blue
    YellowEQURed + Green
    WhiteEQURed + Green + Blue

                            ; MODE Register Settings to access the port control registers
    TRISEQU$0F; Data Direction Register
    PLPEQU$0E; Pull-Up Resistor Enable Register
    LVLEQU$0D; TTL/CMOS Select Register
    STEQU$0C; Schmitt Trigger Enable Register
    WKENEQU$0B; Wake Up Enable Register
    WKEDEQU$0A; Wake Up Edge Select Register
    WKPNDEQU$09; MIWU Pending Register
    CMPEQU$08; Comparator Enable Register
                                                                                                    
    ;------------------------------ VARIABLES ------------------------------
                                                                                                    
    ORG8; Début de mémoire vive utilisable pour stocker les variables du progranne
    LoopCounterDS1; Step Counter
    LineCounterDS2; Line Conter
    FrameCounterDS1; Frame Counter
    FlipFlopDS1; Used to blink pattern


    Juste la déclaration d'une nouvelle variable "FlipFlop" qui sera utile pour la mire clignotante



    La déclaration des macros :

    Citer

    ;-------------------------------- MACRO's -------------------------------
                                                                                                    
    BasicDelayMACROValue; Absorbe un nombre de µcycles = (Value × 4)
    LOCALLocLoop; Etiquette interne à la macro
    movLoopCounter,#Value; 2 µC, initialisation du compteur de bouclettes
    LocLoopDJNZLoopCounter,LocLoop; 4 µC sinon 2 en sortie de boucle
    ENDM

    DelayMACROValue,Offset; Temporisation incluant une franchise (Offset)
    LoopsSET(Value-(Offset))/4
    CyclesSET(Value-(Offset))//4
    REPTLoops/250; Correspond à 250×4 soit 1000 µcycles d'horloge
     BasicDelay250
    ENDR
    BasicDelayLoops//250; Complété par le reste de la division par 250
    IFCycles=3; Afinage
     jmp$+1; Absorbe 3 µcycles en une seule instruction
    ELSE
     REPTCycles; Répétition de NOP modulo 4
       nop
     ENDR
    ENDIF
    ENDM

    WaitMACROValue; Temporisation, inclue les 4 µcycles du bloc d'instructions qui la précéde
     DelayValue,4; Minoration des 4 µcycles
    ENDM

    SetColorMACROColor, Delay; Emission de la couleur (Color), durée = (Delay)
    movw,ra; 1 µC, lecture du port RA
    andw,#%1000; 1 µC, effacement des 3 bits de couleur
    orw,#Color; 1 µC, positionnement des bits impactés
    movra,w; 1 µC, émission de cette nouvelle couleur
    waitDelay; Temporisation, tient compte des µcycles absorbés par les instructions précédentes
    ENDM

    ColorBarsMACRODelayBar; Emission des 8 barres colorées, durée de chaque barre = (DelayBar)
    SetColorWhite,DelayBar; Première barre verticale
    SetColorYellow,DelayBar
    SetColorCyan,DelayBar
    SetColorGreen,DelayBar
    SetColorMagenta,DelayBar
    SetColorRed,DelayBar
    SetColorBlue,DelayBar
    SetColorBlack,DelayBar; La huitième barre est aussi la dernière
    ENDM

    NextLineMACROCurrent,Next; Absorbe 14 µCycles sauf sortie vers MainLoop qui en absorbe que 9
    LOCALLocLab1,LocLab2; Déclaration des étiquettes privées
    djnzLineCounter, LocLab1; 4/2 µC, décomptage sur octet de poids faible
    testLineCounter+1; 1 µC, test de nullité sur l'octet de poids fort
    NextAddrSETNext
    IFNextAddr=MainLoop
     jnzLocLab2; 4/2 µC
     jmp@MainLoop; 1+3 µC, soit 9 consommés au total
    ELSE
     jzNext??:SetUp; 4/2 µC, 7 déjà consommés, les 7 manquants seront absorbés par le setup
     skip; 2 µC, 7 déjà consommés, encore 7 à absorber
    ENDIF
    LocLab1jmp$+3; 3 µC, 7 déjà consommés, encore 7 à absorber
    LocLab2decLineCounter+1; 1 µC, décomptage propagé sur octet de poids fort
    skip; 2 µC, 10 déjà consommés, encore 4 à absorber
    jmp$+1; 3 µC, 10 déjà consommés, plus que 4 à absorber
    nop; 1 µC, 11 déjà consommés, plus que 3 à absorber
    jmpCurrent??:Start; 3 µC, 14 consommés au total
    ENDM

    PresetCountMACROValue; Initialisation du compteur ligne, absorbe 4 µCycles
    movLineCounter,#(Value//256); 2 µC, chargement du compteur, octet de poids faible
    movLineCounter+1,#(Value/256); 2 µC, idem, octet de poids fort
    ENDM


    • Eclatement de l'ancienne macro "Wait" avec création de la macro fille "Delay" issue de cette première :
      • La macro "Wait" nouvelle mouture génère le même délai que l'ancienne en appelant la nouvelle macro "Delay".
      • La nouvelle macro "Delay" génère une temporisation ± un offset passé comme deuxième paramètre.
    • Modifications de la macro "NextLine :
      • Suppression du troisième paramètre et extraction des instructions correspondantes. L'opération de chargement du compteur ligne est transféré à la nouvelle macro "PresetCount".
      • Ajout d'une condition, l'adresse "Next" passée en deuxième paramètre est comparée avec celle de la boucle principale. Si c'est bien l'adresse de cette boucle principale, le programme sera dérouté vers le test des micro-switches de la boucle principale plutôt que de poursuivre son déroulement normal dans la boucle locale.
    • Création de la macro "PresetCount" issue de l'ancienne macro "NextLine".



    Le programme principal en page 0 (adresse 0000H) :

    Citer
                                                    
    LISTF=INHX8M

    ;-------------------------- ROUTINE D'INTERRUPTION --------------------------
                                                                                                    
    ORG0
    Interruptreti

    ;-------------------------- ROUTINE D'INITIALISATION -------------------------
                                                                                                    
    ORG8
    Initializemovra,#%0000; Set port A low
    movrb,#%11111111; Set port B high
    movrc,#%11111111; Set port C high

                            ; Pull-Up Resistor Configuration
    modePLP; Allow Pull-Up Resistor configuration
    mov!ra,#%1111; Set port A, bit 0-3 to normal
    mov!rb,#%00001111; Set port B bits 4-7 with pull-up resistors
    mov!rc,#%00000000; Set port C bits 0-7 with pull-up resistors
                                                                                                    
                            ; Port Direction Configuration
    modeTRIS; Allow Direction configuration
    mov!ra,#%0000; Set port A bits 0-3 to output
    mov!rb,#%11110000; Set port B bits 0-3 to output, 4-7 to input
    mov!rc,#%11111111; Set port C bits 0-7 to input
                                                                                                    
                            ; Device Configuration Options
    mov!option,#%01111111; Raz bit RTW, RTCC inhibé, WREG accessible à la place
                                                                                                    
    ;---------------------------- PROGRAMME PRINCIPAL -----------------------------
                                                                                                    
    MainsetbSyncH
    setbSyncV
    clrFlipFlop; Initialisation du flip flop
    jmpPresetFrCnt

                            ; Compteur de trames pour clignotement, absorbe 7 µCycles
    MainLoopdjnzFrameCounter,NoPreset; 2/4 µC
    notFlipFlop; 1 µC, inversion du flip flop
    PresetFrCntmovFrameCounter,#30; 2 µC, clignotement toutes les 30 trames (½ seconde)
    skip; 2 µC, ajustement à 7 µC si rechargement FrameCount
    NoPresetjmp$+1; 3 µC, ajustement à 7 µCycles pour décomptage normal
                                                                                                    
                            ; Lecture de la fréquence ligne sur les 2 premiers microswitches.
    ; Absorbe 11 µCycles quelque soit la boucle à exécuter.
    jnbrb.5,Jmp31k; 2/4 µC, lecture de la fréquence programmée par les dip-switches
    jnbrb.4,Jmp24k; 2/4 µC
    Jmp15kjmp$+1; 3 µC pour ajustage absorpsion à 11 µC
    jmp@Start15k; 1+3 µC, instruction de page incluse avec "@"
    Jmp24knop; 1 µC pour ajustage absorpsion à 11 µC
    jmp@Start24k; 1+3 µC, instruction de page incluse avec "@"
    Jmp31kjmp$+1; 3 µC pour ajustage absorpsion à 11 µC
    jmp@Start31k; 1+3 µC, instruction de page incluse avec "@"
                                                                                                    

    Ajout des tests :
    • Sur le compteur trame. La variable "FlipFlop" est inversée toutes les trente trames, donc la mire concernée clignotera toutes les ½ secondes environ.
    • Sur les deux premiers micro-switches. L'exécution du programme continuera dans la boucle locale (la page de 512 octets) correspondant à la fréquence ligne programmée.



    Il y a donc 3 boucles locales, une pour chaque fréquence ligne.

    Chaque boucle locale correspond à une trame, elle est composée de 4 blocs dont chacun est constitué de la répétition d'un nombre fixe de lignes dépendant de la fréquence ligne utilisée :
    • L'impulsion de synchronisation trame. Le signal correspondant est à zéro pendant cette période.
    • Le champ à la suite de l'impulsion trame, le signal vidéo est au niveau du noir pendant cette période.
    • Les lignes affichant la mire, les couleurs de la mire sont affichées pendant cette période.
    • Le champ précédant l'impulsion trame, le signal vidéo est au niveau du noir pendant cette période.
    C'est en fin d'exécution de ce dernier bloc, c'est à dire à la fin de la trame, que le contrôle est transféré de la boucle locale vers la boucle principale pour incrémenter le compteur de trame et lire la fréquence ligne programmée sur les micro-switches.

    Chaque ligne à l'intérieur d'un bloc est décomposée en 4 périodes distinctes dépendantes de la fréquence utilisée :
    • L'impulsion de synchronisation ligne. Le signal correspondant est à zéro pendant cette période.
    • Le palier arrière (back porch), le signal vidéo est au niveau du noir pendant ce palier.
    • Le contenu de la ligne, il est affiché uniquement pendant cette période.
    • Le palier avant (front porch), le signal vidéo est au niveau du noir pendant ce palier.
    C'est en fin de ce dernier palier que le compteur ligne est décrémenté, le déroulement du bloc correspondant à un champ de la trame est terminée quand ce compteur ligne s'annule, l'exécution est alors transférée dans le bloc suivant.

    Le code des 3 pages est identique aux noms des étiquettes près, il n'y a que les valeurs des paramètres (nombre de µcycles, nombre de lignes) passées aux macros qui diffèrent :



    Le programme générant les mires à 15 kHz en page 1 (adresse 0200H)

    Citer
                                                    
    ORG$0200
    Start15kEQU$

    ;****************************** Impulsion de synchronisation trame ******************************
                                                                                                    
    SyncHor15kSET$
    :SetUpPresetCount3; Nombre de lignes allouées à l'impulsion de synchronisation verticale
    jmpSyncHor15k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    SyncHor15kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait323; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes tout pendant la durée de l'impulsion de synchronisation trame
    SetColorBlack,2456+161-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineSyncHor15k,Lagging15k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    SyncHor15kSET$
    :Startmovw,rb; 1 µC, lecture du port RB, manipulation de bits sur W à partir de WREG
    clrbwreg.0; 1 µC, positionnement du bit affecté à la synchronisation horizontale
    clrbwreg.1; 1 µC, positionnement du bit affecté à la synchronisation verticale
    movrb,w; 1 µC, émission de cette nouvel état
    Wait238; Durée de l'impulsion ligne
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpSyncHor15k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;********** Champ à la suite de l'impulsion de synchronisation trame ( blanking arrière) **********
                                                                                                    
    Lagging15kSET$
    :SetUpPresetCount23; Nombre de lignes allouées au blanking arrière
    jmpLagging15k:Start

                            ; Palier de suppression arrière(Back Porch),suite
    Lagging15kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait323; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes à la suite de l'impulsion de synchronisation trame
    SetColorBlack,2456+161-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineLagging15k,Pattern15k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    Lagging15kSET$
    :Startmovw,rb; 1 µC, lecture du port RB, manipulation de bits sur W à partir de WREG
    clrbwreg.0; 1 µC, positionnement du bit affecté à la synchronisation horizontale
    setbwreg.1; 1 µC, effacement du bit affecté à la synchronisation verticale
    movrb,w; 1 µC, émission de cet nouvel état
    Wait238; Durée de l'impulsion ligne
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpLagging15k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;****************************** Affichage du motif de la mire ******************************
                                                                                                    
    Pattern15kSET$
    :SetUpPresetCount224; 224 Nombre de lignes allouées pour afficher la mire
    jmpPattern15k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    Pattern15kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait323; Durée du palier arrière
                                                                                                    
                            ; Affichage des 8 barres colorées de la mire
    ColorBars307; Chaque barre occupe 307 µcycles
                                                                                                    
                            ; Palier de suppression avant (Front Porch)
    SetColorBlack,161-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLinePattern15k,Leading15k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    Pattern15kSET$
    :Startjmp$+1; Absorption de 3 µcycles
    clrbSyncH; Emission de l'impulsion SyncH
    Wait238; Durée de l'impulsion
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpPattern15k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;************** Champ précédant l'impulsion de synchronisation trame (blanking avant) **************
                                                                                                    
    Leading15kSET$
    :SetUpPresetCount13; 4 µC, nombre de lignes allouées au blanking avant
    jmpLeading15k:Start; 3 µCycles

                            ; Palier de suppression arrière (Back Porch), suite
    Leading15kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait323; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes précédant l'impulsion de synchronisation trame
    ; Le nombre de µcycles doit être minoré de 34 pour lire les micro-switches lors du rebouclage par MainLoop
    ; 34 µcycles = 9 (NextLine) + 18 (MainLoop) + 7 (SyncHor××k:SetUp)
    SetColorBlack,2456+161-34; Contenu = niveau du noir + palier avant, minoré de 34 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineLeading15k,MainLoop; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    ; Un délai supplémentaire de 20 µCycles (34-14) doit être inséré car le test du compteur n'en a consommé que 14
    Leading15kSET$
    :StartDelay20,-3; Délai majoré de 3 µcycles pour remplacer le conventionnel "jmp $+1"
    clrbSyncH; Emission de l'impulsion SyncH
    Wait238; Durée de l'impulsion
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpLeading15k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    



    Le programme générant les mires à 24 kHz en page 2 (adresse 0400H)

    Citer
                                                    
    ORG$0400
    Start24kEQU$

    ;****************************** Impulsion de synchronisation trame ******************************
                                                                                                    
    SyncHor24kSET$
    :SetUpPresetCount4; Nombre de lignes allouées à l'impulsion de synchronisation verticale
    jmpSyncHor24k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    SyncHor24kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait222; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes tout pendant la durée de l'impulsion de synchronisation trame
    SetColorBlack,1536+142-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineSyncHor24k,Lagging24k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    SyncHor24kSET$
    :Startmovw,rb; 1 µC, lecture du port RB, manipulation de bits sur W à partir de WREG
    clrbwreg.0; 1 µC, positionnement du bit affecté à la synchronisation horizontale
    clrbwreg.1; 1 µC, positionnement du bit affecté à la synchronisation verticale
    movrb,w; 1 µC, émission de cette nouvel état
    Wait150; Durée de l'impulsion ligne
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpSyncHor24k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;********** Champ à la suite de l'impulsion de synchronisation trame ( blanking arrière) **********
                                                                                                    
    Lagging24kSET$
    :SetUpPresetCount25; Nombre de lignes allouées au blanking arrière
    jmpLagging24k:Start

                            ; Palier de suppression arrière(Back Porch),suite
    Lagging24kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait222; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes à la suite de l'impulsion de synchronisation trame
    SetColorBlack,1536+142-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineLagging24k,Pattern24k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    Lagging24kSET$
    :Startmovw,rb; 1 µC, lecture du port RB, manipulation de bits sur W à partir de WREG
    clrbwreg.0; 1 µC, positionnement du bit affecté à la synchronisation horizontale
    setbwreg.1; 1 µC, effacement du bit affecté à la synchronisation verticale
    movrb,w; 1 µC, émission de cet nouvel état
    Wait150; Durée de l'impulsion ligne
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpLagging24k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;****************************** Affichage du motif de la mire ******************************
                                                                                                    
    Pattern24kSET$
    :SetUpPresetCount384; Nombre de lignes allouées pour afficher la mire
    jmpPattern24k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    Pattern24kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait222; Durée du palier arrière
                                                                                                    
                            ; Affichage des 8 barres colorées de la mire
    ColorBars1536/8; Chaque barre occupe 192 µcycles
                                                                                                    
                            ; Palier de suppression avant (Front Porch)
    SetColorBlack,142-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLinePattern24k,Leading24k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    Pattern24kSET$
    :Startjmp$+1; Absorption de 3 µcycles
    clrbSyncH; Emission de l'impulsion SyncH
    Wait150; Durée de l'impulsion
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpPattern24k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;************** Champ précédant l'impulsion de synchronisation trame (blanking avant) **************
                                                                                                    
    Leading24kSET$
    :SetUpPresetCount11; Nombre de lignes allouées au blanking avant
    jmpLeading24k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    Leading24kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait222; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes précédant l'impulsion de synchronisation trame
    ; Le nombre de µcycles doit être minoré de 34 pour lire les micro-switches lors du rebouclage par MainLoop
    ; 34 µcycles = 9 (NextLine) + 18 (MainLoop) + 7 (SyncHor××k:SetUp)
    SetColorBlack,1536+142-34; Contenu = niveau du noir + palier avant, minoré de 34 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineLeading24k,MainLoop; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    ; Un délai supplémentaire de 20 µCycles (34-14) doit être inséré car le test du compteur n'en a consommé que 14
    Leading24kSET$
    :StartDelay20,-3; Délai majoré de 3 µcycles pour remplacer le conventionnel "jmp $+1"
    clrbSyncH; Emission de l'impulsion SyncH
    Wait150; Durée de l'impulsion
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpLeading24k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    



    Le programme générant les mires à 31 kHz en page 3 (adresse 0600H)

    Citer
                                                    
    ORG$0600
    Start31kEQU$

    ;****************************** Impulsion de synchronisation trame ******************************
                                                                                                    
    SyncHor31kSET$
    :SetUpPresetCount3; Nombre de lignes allouées à l'impulsion de synchronisation verticale
    jmpSyncHor31k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    SyncHor31kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait161; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes tout pendant la durée de l'impulsion de synchronisation trame
    SetColorBlack,1184+81-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineSyncHor31k,Lagging31k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    SyncHor31kSET$
    :Startmovw,rb; 1 µC, lecture du port RB, manipulation de bits sur W à partir de WREG
    clrbwreg.0; 1 µC, positionnement du bit affecté à la synchronisation horizontale
    clrbwreg.1; 1 µC, positionnement du bit affecté à la synchronisation verticale
    movrb,w; 1 µC, émission de cette nouvel état
    Wait152; Durée de l'impulsion ligne
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpSyncHor31k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;********** Champ à la suite de l'impulsion de synchronisation trame ( blanking arrière) **********
                                                                                                    
    Lagging31kSET$
    :SetUpPresetCount33; Nombre de lignes allouées au blanking arrière
    jmpLagging31k:Start

                            ; Palier de suppression arrière(Back Porch),suite
    Lagging31kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait161; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes à la suite de l'impulsion de synchronisation trame
    SetColorBlack,1184+81-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineLagging31k,Pattern31k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    Lagging31kSET$
    :Startmovw,rb; 1 µC, lecture du port RB, manipulation de bits sur W à partir de WREG
    clrbwreg.0; 1 µC, positionnement du bit affecté à la synchronisation horizontale
    setbwreg.1; 1 µC, effacement du bit affecté à la synchronisation verticale
    movrb,w; 1 µC, émission de cet nouvel état
    Wait152; Durée de l'impulsion ligne
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpLagging31k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;****************************** Affichage du motif de la mire ******************************
                                                                                                    
    Pattern31kSET$
    :SetUpPresetCount480; Nombre de lignes allouées pour afficher la mire
    jmpPattern31k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    Pattern31kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait161; Durée du palier arrière
                                                                                                    
                            ; Affichage des 8 barres colorées de la mire
    ColorBars1184/8; Chaque barre occupe 148 µcycles
                                                                                                    
                            ; Palier de suppression avant (Front Porch)
    SetColorBlack,81-14; Contenu = niveau du noir + palier avant, minoré de 14 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLinePattern31k,Leading31k; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    Pattern31kSET$
    :Startjmp$+1; Absorption de 3 µcycles
    clrbSyncH; Emission de l'impulsion SyncH
    Wait152; Durée de l'impulsion
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpPattern31k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    ;************** Champ précédant l'impulsion de synchronisation trame (blanking avant) **************
                                                                                                    
    Leading31kSET$
    :SetUpPresetCount14; Nombre de lignes allouées au blanking avant
    jmpLeading31k:Start

                            ; Palier de suppression arrière (Back Porch), suite
    Leading31kSET$
    :LoopsetbSyncH; Effacement de l'impulsion de synchronisation horizontale
    Wait161; Durée du palier arrière
                                                                                                    
                            ; Blanking des lignes précédant l'impulsion de synchronisation trame
    ; Le nombre de µcycles doit être minoré de 34 pour lire les micro-switches lors du rebouclage par MainLoop
    ; 34 µcycles = 9 (NextLine) + 18 (MainLoop) + 7 (SyncHor××k:SetUp)
    SetColorBlack,1184+81-34; Contenu = niveau du noir + palier avant, minoré de 34 µcycles
                                                                                                    
                            ; Décomptage des lignes du bloc en fin du palier de suppression avant (14 µcycles)
    NextLineLeading31k,MainLoop; Décomptage lignes et test si zéro
                                                                                                    
                            ; Impulsion de synchronisation horizontale
    ; Un délai supplémentaire de 20 µCycles (34-14) doit être inséré car le test du compteur n'en a consommé que 14
    Leading31kSET$
    :StartDelay20,-3; Délai majoré de 3 µcycles pour remplacer le conventionnel "jmp $+1"
    clrbSyncH; Emission de l'impulsion SyncH
    Wait152; Durée de l'impulsion
                                                                                                    
                            ; Palier de suppression arrière (Back Porch)
    jmpLeading31k:Loop; Rebouclage avec absorption de 3 µcycles
                                                                                                    
    END



    Pour l'instant le générateur ne délivre qu'un seul type de mire : celle à barre colorée, la prochaine étape sera l'inclusion de l'une ou l'autre de ces mires clignotantes dans chaque boucle locale.

       
    « Modifié: Mardi 06 Octobre 2015, 21:56:09 pm par gc339 »
    Le repos, c'est fait pour les jeunes. Ils ont toute la vie devant eux. J. Gabin/M. Audiard



    Hors ligne AsPiC

    • Admin
    • Dieu de l' Arcade
    • *****
    • Messages: 8508
    • Localisation: Les Herbiers (85)
    • Present pour Koh Lanta Retrogaming Party 2069 !
      • Voir le profil
      • Mon compte Instagram !!
    Etude/Réalisation d'un générateur de mires 15/24/31 kHz
    « Réponse #15 le: Vendredi 07 Juin 2013, 16:35:53 pm »
  • Merci gc339 pour ton boulot sur ce générateur de mire qui s'annonce indispensable ^-^


    Recherche tout élément de Jeutel Galaktron - "AsPiC c'est : no WIP but just RIP" - kos71 2014