home *** CD-ROM | disk | FTP | other *** search
/ PC/CD FUN 24 / cdimage.iso / dos / GFX2 / TECH_FRA.TXT < prev    next >
Encoding:
Text File  |  1996-12-12  |  30.5 KB  |  702 lines

  1. ┌────────────────────────────────────────────────────────────────────────────┐
  2. │░▒▓█     Doc. technique pour GrafX 2.00 - Version 1.03 (12/12/1996)     █▓▒░│
  3. └────────────────────────────────────────────────────────────────────────────┘
  4.  
  5. Ce fichier traite:
  6.  
  7.   - du format d'image PKM
  8.   - des valeurs à envoyer au CRTC pour avoir accès à tous les modes vidéos
  9.     incroyables disponibles dans GrafX 2.00
  10.  
  11.  
  12.  
  13. ┌────────────────────────────────────────────────────────────────────────────┐
  14. │            ░▒▓█ Le format d'image PKM - par Karl Maritaud █▓▒░             │
  15. └────────────────────────────────────────────────────────────────────────────┘
  16.  
  17.  
  18.     Tout d'abord, je tiens a dire que j'ai créé ce format il y a déjà quelques
  19.   années, à l'époque où je ne savais pas comment charger les meilleurs formats
  20.   (GIF par exemple) et que je voulais également avoir mon propre format.
  21.     Le format PKM a été conçu pour être très simple, facile à encoder et à
  22.   décoder. De plus, son header est très simple (court) et evolutif.
  23.     Le seul vrai défaut que je puisse y trouver est que l'on ne peut sauver
  24.   des images qu'en 256 couleurs.
  25.     Je sais que vous allez vous dire:
  26.       "Oh non! Encore un nouveau format à la con! J'm'en servirai jamais! En
  27.       plus le taux de compression est naze! Je prefère le GIF!".
  28.     Et je répondrai:
  29.       "Ouais! T'as raison. Mais si tu ne sais pas comment charger du GIF et
  30.       que tu veux un format simple avec une compression correcte (du moins sur
  31.       les images simples), il peut être utile."
  32.  
  33.   Donc, voici la documentation de ce format...
  34.  
  35.  
  36.  
  37. Le HEADER:
  38. ══════════
  39.  
  40.   Le header est la structure de 780 octets suivante. (Ne vous inqiétez pas à
  41.   propos de la taille. C'est tout simplement parce que la palette fait partie
  42.   du header).
  43.  
  44.  
  45.   ┌─────┬───────────┬──────┬──────┬──────────────────────────────────────────┐
  46.   │ Pos │ Champ     │ Type │Taille│ Description                              │
  47.   ╞═════╪═══════════╪══════╪══════╪══════════════════════════════════════════╡
  48.   │   0 │ Signature │ char │   3  │ Chaîne constante "PKM" (SANS délimitation│
  49.   │     │           │      │      │ de taille '\0' ou autres...)             │
  50.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  51.   │   3 │ Version   │ byte │   1  │ Pour le moment, ce champ ne peut prendre │
  52.   │     │           │      │      │ que la valeur 0.                         │
  53.   │     │           │      │      │ D'autres méthodes de compression pourront│
  54.   │     │           │      │      │ la modifier mais pour l'instant il n'y en│
  55.   │     │           │      │      │ a qu'une seule.                          │
  56.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  57.   │   4 │ Pack_byte │ byte │   1  │ Valeur de l'octet de reconnaissance pour │
  58.   │     │           │      │      │ les répétitions de couleurs codées sur 1 │
  59.   │     │           │      │      │ Octet. (Voir la section sur la méthode de│
  60.   │     │           │      │      │ compression pour plus d'informations)    │
  61.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  62.   │   5 │ Pack_word │ byte │   1  │ Valeur de l'octet de reconnaissance pour │
  63.   │     │           │      │      │ les répétitions de couleurs codées sur 2 │
  64.   │     │           │      │      │ Octets. (Voir la section sur la méthode  │
  65.   │     │           │      │      │ de compression pour plus d'informations) │
  66.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  67.   │   6 │ Largeur   │ word │   2  │ Largeur de l'image (en pixels)           │
  68.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  69.   │   8 │ Hauteur   │ word │   2  │ Hauteur de l'image (en pixels)           │
  70.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  71.   │  10 │ Palette   │ byte │ 768  │ Palette RGB (RGB RGB ... 256 fois) avec  │
  72.   │     │           │      │      │ des valeurs de 0 à 63. Je sais que le    │
  73.   │     │           │      │      │ standard dans les fichiers d'images est  │
  74.   │     │           │      │      │ de 0 à 255 mais je trouve ça crétin!     │
  75.   │     │           │      │      │ C'est tellement plus simple d'envoyer la │
  76.   │     │           │      │      │ palette toute entière dans le port 3C9h  │
  77.   │     │           │      │      │ avec un REP OUTSB sans avoir à convertir │
  78.   │     │           │      │      │ la palette.                              │
  79.   ├─────┼───────────┼──────┼──────┼──────────────────────────────────────────┤
  80.   │ 778 │ Taille_PH │ word │   2  │ Taille du Post-header. C'est le nombre   │
  81.   │     │           │      │      │ d'octets entre le header et les données  │
  82.   │     │           │      │      │ de l'image. Cette valeur peut valoir 0.  │
  83.   └─────┴───────────┴──────┴──────┴──────────────────────────────────────────┘
  84.  
  85.   Les données du type "word" sont stockées selon les conventions d'Intel:
  86.   c'est-à-dire l'octet de poids le plus faible en premier.
  87.  
  88.  
  89.  
  90. Le POST-HEADER:
  91. ═══════════════
  92.  
  93.   Le post-header a une taille variable. Il a été conçu pour supporter les
  94. nouvelles fonctions de ce format sans avoir a changer complètement le format.
  95.  
  96.   Il est constitué d'identificateurs de champ suivis par leur taille et leur
  97. contenu.
  98.   Un identificateur de champ est codé sur 1 octet ainsi que sa taille.
  99.  
  100.  
  101.   Ces identificateurs de champ sont:  (cette liste peut être rallongée...)
  102.   ──────────────────────────────────
  103.  
  104.     0 : Commentaire sur l'image
  105.     1 : Dimensions de l'écran d'origine
  106.  
  107.   Si vous rencontrez un champ inconnu par votre routine de chargment, sautez
  108.   simplement au delà. Mais, par contre, si un champ vous dit de sauter à une
  109.   position qui tombe après le début théorique des données de l'image, alors
  110.   c'est qu'il y a une erreur dans le fichier.
  111.  
  112.  
  113.   Les champs:
  114.   ───────────
  115.  
  116.     * Commentaire:
  117.  
  118.       Grâce à ce champ, les artistes vont pouvoir commenter leurs dessins.
  119.       Notez que GrafX 2 a une taille limite de commentaire de 32 caractères.
  120.       Mais vous pourrez avoir des commentaires allant jusqu'à 255 caractères
  121.       si vous créez votre propre viewer puisque GrafX 2 ignorera simplement
  122.       les caractères en trop.
  123.  
  124.       Exemple: [0],[16],[Dessin de X-Man]
  125.       Cette séquence signifie:
  126.         - le champ est un commentaire
  127.         - le commentaire a une taille de 16 caractères (il n'y a pas de
  128.           caractère de fin de chaîne puisque vous connaissez sa taille)
  129.         - le commentaire est "Dessin de X-Man"
  130.  
  131.     * Dimensions de l'écran d'origine:
  132.  
  133.       Puisque GrafX 2 propose un énorme choix de résolutions, il a semblé
  134.       pratique d'ajouter un champ indicant quelles étaient les dimensions de
  135.       l'écran d'origine.
  136.  
  137.       Exemple: [1],[4],[320],[256]
  138.       Cette séquence signifie:
  139.         - Le champ décrit les dimensions de l'écran d'origine
  140.         - Les dimensions sont 2 words (donc cette valeur doit être égale à 4)
  141.         - La largeur de l'écran d'origine était de 320 pixels
  142.         - La hauteur de l'écran d'origine était de 256 pixels
  143.  
  144.       Notez que les words stockés dans les champs sont écrits à la manière
  145.       Intel. La BETA-version 90% ne respectait pas cette norme (désolé).
  146.       Ce n'est pas bien grâve mais les images sauvées avec la version 90% et
  147.       rechargées avec une version postérieure (91% et plus) ne passeront pas
  148.       dans la bonne résolution.
  149.  
  150.  
  151. La METHODE DE COMPACTAGE DE L'IMAGE:
  152. ════════════════════════════════════
  153.  
  154.   La méthode de compression PKM est une sorte de "Run-Length-Compression" qui
  155. est très efficace sur les images comportant de longues répétitions d'une même
  156. couleur horizontalement.
  157.   En fait la compression commence à être efficace s'il y a souvent plus de 3
  158. fois la même color consécutivement.
  159.  
  160.   Je pense qu'il est préférable de vous donner directement l'algorithme plutôt
  161. que de nager dans des explications incomprehensibles.
  162.  
  163.  
  164.   DEBUT
  165.     /*
  166.       fonctions:
  167.         Lire_octet(Fichier)            Lit et retourne 1 octet à partir de
  168.                                      Fichier
  169.         Dessiner_pixel(X,Y,Couleur)    Dessine un pixel d'une certaine Couleur
  170.                                      à la position (X,Y)
  171.         Taille_fichier(Fichier)        Retourne la taille totale d'un Fichier
  172.                                      en octets
  173.  
  174.       variables:
  175.         le type de Taille_image        est dword
  176.         le type de Taille_donnees      est dword
  177.         le type de Compteur_donnees    est dword
  178.         le type de Compteur_pixels     est dword
  179.         le type de Couleur             est byte
  180.         le type de Octet_lu            est byte
  181.         le type de Word_lu             est word
  182.         le type de Compteur            est word
  183.         le type de Fichier             est <fichier> (dépend du langage)
  184.     */
  185.  
  186.     /* A cet endroit, le header et le post-header ont déjà été lus. */
  187.  
  188.     Taille_image        <- Header.Largeur * Header.Hauteur
  189.     Taille_donnees      <- Taille_fichier(Fichier) - (780+Header.Taille_PH)
  190.  
  191.     Compteur_donnees    <- 0
  192.     Compteur_pixels     <- 0
  193.  
  194.     Octet_lu            <- Lire_octet(Fichier)
  195.  
  196.     /* Boucle de décompression: */
  197.     TANT QUE ((Compteur_pixels<Taille_image)
  198.            ET (Compteur_donnees<Taille_donnees)) FAIRE
  199.     {
  200.  
  201.       /* Si pas un octet de reconnaissance de paquet, c'est un pixel brut */
  202.       SI ((Octet_lu<>Header.Pack_byte) ET (Octet_lu<>Header.Pack_word))
  203.       ALORS
  204.       {
  205.         Dessiner_pixel(Compteur_pixels MOD Header.Largeur,
  206.                        Compteur_pixels DIV Header.Largeur,
  207.                        Octet_lu)
  208.  
  209.         Compteur_pixels  <- Compteur_pixels + 1
  210.         Compteur_donnees <- Compteur_donnees + 1
  211.         Octet_lu         <- Lire_octet(Fichier)
  212.       }
  213.       SINON   /* Est-ce que le nombre de pixels à répéter est codé... */
  214.       {       /* ... sur 1 octet ? */
  215.         SI (Octet_lu = Header.Pack_byte) ALORS
  216.         {
  217.           Couleur  <- Lire_octet(Fichier)
  218.           Octet_lu <- Lire_octet(Fichier)
  219.  
  220.           POUR Compteur ALLANT DE 0 A (Octet_lu-1) PAR PAS DE +1
  221.             Dessiner_pixel((Compteur_pixels+Compteur) MOD Header.Largeur,
  222.                            (Compteur_pixels+Compteur) DIV Header.Largeur,
  223.                            Couleur)
  224.  
  225.           Compteur_pixels  <- Compteur_pixels + Octet_lu
  226.           Compteur_donnees <- Compteur_donnees + 3
  227.           Octet_lu         <- Lire_octet(Fichier)
  228.         }
  229.         SINON /* ... sur 2 octets ? */
  230.         {
  231.           Couleur <- Lire_octet(Fichier)
  232.           Word_lu <- (word) (Lire_octet(Fichier) SHL 8)+Lire_octet(Fichier)
  233.  
  234.           POUR Compteur ALLANT DE 0 A (Word_lu-1) PAR PAS DE +1
  235.             Dessiner_pixel((Compteur_pixels+Compteur) MOD Header.Largeur,
  236.                            (Compteur_pixels+Compteur) DIV Header.Largeur,
  237.                            Couleur)
  238.  
  239.           Compteur_pixels  <- Compteur_pixels + Word_lu
  240.           Compteur_donnees <- Compteur_donnees + 4
  241.           Octet_lu         <- Lire_octet(Fichier)
  242.         }
  243.       }
  244.  
  245.     }
  246.   FIN
  247.  
  248.  
  249.   Par exemple, la séquence suivante:
  250.     (on suppose que Pack_byte=01 et Pack_word=02)
  251.     04 03 01 05 06 03 02 00 01 2C
  252.   sera décodée comme:
  253.     04 03 05 05 05 05 05 05 03 00 00 00 ... (repéter 0 300 fois (012Ch=300))
  254.  
  255.   Les répétitions qui tiennent sur un word doivent être écrites avec leur
  256.   octet de poids le plus fort en premier. Je sais que ça va à l'encontre du
  257.   standard Intel mais puisque je lis les octets du fichier au travers d'un
  258.   buffer (franchement plus rapide), Je me fous complètement de l'ordre
  259.   (Désolé :)). Mais les words du header et du post-header doivent être écrits
  260.   et lus à la manière Intel!
  261.  
  262.  
  263.   Conseils de compactage:
  264.   ───────────────────────
  265.  
  266.   * Comme vous pouvez le constater, il pourrait y avoir un problème lorsque
  267.   vous devriez compacter un pixel brut de couleur egale à Pack_byte ou à
  268.   Pack_word. Ces pixels doivent toujours être codés comme des paquets même
  269.   s'il n'y a qu'un seul pixel.
  270.  
  271.     Exemple: (supposons que Pack_byte=9)
  272.       9   sera encodé 9,9,1     (Le 1er 9 dans la séquence...
  273.       9,9 sera encodé 9,9,2     ... encodée est Pack_byte)
  274.       etc...
  275.  
  276.   * Il semble évident de trouver des valeurs pour Pack_byte et Pack_word qui
  277.   ne sont jamais (ou presque) utilisées. Donc, une petite routine qui trouve
  278.   les 2 couleurs les moins utilisées dans l'image devrait être appelée avant
  279.   avant de commencer la compression. Ceci peut être réalisé presque instanta-
  280.   nément en Assembleur.
  281.  
  282.   * Quand vous voulez écrire une séquence de 2 couleurs identiques, écrivez
  283.   simplement ces 2 couleurs l'une après l'autre (Couleur,Couleur) puisque ça
  284.   ne prend que 2 octets au lieu de 3 si vous aviez écrit un paquet (Pack_byte,
  285.   Couleur,2).
  286.  
  287.   * Si vous compressez une image extrêmement simple qui comporte une séquence
  288.   de plus de 65535 fois la même couleur consécutivement, vous devez "casser"
  289.   la séquence et continuer avec un nouveau paquet.
  290.  
  291.     Exemple: vous devez compacter les 65635 mêmes octets consécutifs (de
  292.              couleur 0 par exemple)
  293.       (On suppose que Pack_byte=01 et Pack_word=02)
  294.       Vous devrez alors écrire: 02 00 FF FF 01 00 64    (FFFFh=65535, 64h=100)
  295.  
  296.  
  297.  
  298. ┌────────────────────────────────────────────────────────────────────────────┐
  299. │            ░▒▓█ Passer dans les modes vidéos de GrafX 2.00 █▓▒░            │
  300. └────────────────────────────────────────────────────────────────────────────┘
  301.  
  302.  
  303.     Toutes les procédures d'initialisation de mode sont écrites en ASM 386. De
  304.   toutes façons, si vous ne comprenez pas une ligne d'ASM, je ne vois vraiment
  305.   pas à quoi pourront vous servir ces procédures.
  306.  
  307.     Elles ont été conçues pour être utilisées dans le modèle de mémoire FLAT.
  308.   Mais cela ne devrait pas vous prendre trop de temps de les adapter au modèle
  309.   que vous souhaitez utiliser puisqu'il n'y a que les manipulations de mémoire
  310.   que cela affectera (utilisez donc DS:SI au lieu de ESI, ES:DI à la place de
  311.   EDI et faîtes attention à l'adresse 0A0000h qui se transforme en l'adresse
  312.   0A000h:00000h).
  313.  
  314.  
  315. MCGA: (Mode VGA standard)
  316. ═════
  317.  
  318.     Y-a-t'il quelqu'un sur cette planète qui ne sache toujours pas comment
  319.   on passe en mode MCGA 320x200 en 256 couleurs ??!?
  320.     Bon... Je suppose que vous êtes un novice si vous lisez les 2 lignes
  321.   suivantes :)
  322.  
  323.  
  324.     mov  ax,0013h
  325.     int  10h
  326.  
  327.  
  328.  
  329. Modes X: (Modes VGA étendus)
  330. ════════
  331.  
  332.     Bien... Il me semble que le Mode X original était en 320x240, mais
  333.   maintenant tout le monde appelle "Modes X" (ou X-Modes) tous les modes VGA
  334.   qui utilise plus de 64Ko de mémoire vidéo et la structure "Chain-4".
  335.     Afficher un pixel dans n'importe quel Mode X peut être effectué par la
  336.   même et unique fonction (mais je ne vous expliquerai pas comment faire, il
  337.   vous suffit d'indiquer à la fonction la taille des plans (Largeur/4)).
  338.     Si vous ne comprenez rien à ce que je dis, (Chain-4, plans...) il vous
  339.   suffit de lire n'importe quelle bonne documentation sur le Mode X.
  340.  
  341.  
  342.     Nous tenons à remercier les auteurs de XLIB2 pour nous avoir économisé du
  343.   temps en ayant écrit cette fonction. Nous l'avons légèrement optimisée en
  344.   fonction de nos besoins, mais l'essentiel en a été conservé.
  345.  
  346.  
  347.     mov  ax,13h      ; Oui! Encore le mode MCGA! Tous les Modes X doivent
  348.     int  10h         ; commencer à partir du mode VGA standard, mais bien des
  349.                      ; choses changent par la suite.
  350.  
  351.     mov  dx,3C4h     ; Nous allons demander au registre TIMING SEQUENCER de
  352.     mov  ax,0604h    ; passer dans le mode "Unchained" (X-mode), sans gérer de
  353.     out  dx,ax       ; parité, et un accès au 256Ko de la carte vidéo.
  354.     mov  ax,0100h    ; On va ensuite enclencher le reset synchrone du registre
  355.     out  dx,ax       ; TS car on s'apprête à jouer avec les registres.
  356.  
  357.     mov  esi,X_ptr   ; Pointeur sur la liste des constantes à envoyer au CRTC.
  358.     cld
  359.  
  360.     lodsb            ; Ceci charge dans AL une valeur qui nous dira quoi faire
  361.                      ; avec le registre MISCELLANEOUS, et incrémente ESI.
  362.                      ; La valeur est égale à ZERO => Rien à faire
  363.                      ;                      sinon => Envoyer AL au reg. MISC.
  364.  
  365.     or   al,al       ; Devons nous modifier le mode vidéo de base ?
  366.     jz   NonMerci    ; Non?─┐ En fait, la réponse est toujours "Oui".
  367.     mov  dx,3C2h     ;      │ Sauf pour quelques modes tels que le
  368.     out  dx,al       ;      │ 320x200 en Mode X
  369.     NonMerci:        ; <────┘ (mais notre mode 320x200 est en MCGA...)
  370.  
  371.     mov  dx,3C4h     ; On en a terminé avec les manipulations du registre
  372.     mov  ax,0300h    ; MISCELLANEOUS, on peut maintenant désenclencher le
  373.     out  dx,ax       ; reset synchrone du registre TIMING SEQUENCER.
  374.  
  375.     ; Et maintenant, si on jouait avec le CRTC?
  376.  
  377.     mov  dx,3D4h     ; Dans le 18ème registre du CRTC, on va désenclencher le
  378.     mov  al,11h      ; bit de protection. Sans cela, les valeurs que nous
  379.     out  dx,al       ; aurions envoyées aux registres du CRTC auraient été
  380.     inc  dx          ; ignorées.
  381.     in   al,dx
  382.     and  al,7Fh
  383.     out  dx,al
  384.  
  385.     dec  dx          ; DX pointe à nouveau sur "l'entrée" du registre CRTC.
  386.     lodsb            ; Ceci met dans AL le nombre de registres CRTC à changer
  387.     xor  ecx,ecx     ; On doit nettoyer ECX avant de commencer à répéter...
  388.     mov  cl,al       ; ...CL (AL) fois OUTSW
  389.     rep  outsw       ; On peut envoyer la sauce aux registres du CRTC!
  390.  
  391.     ; Juste au cas où le 20ème registre CRTC aurait été oublié dans la table
  392.     ; d'initialisation, on peut le calculer nous-mêmes (Ouaip, on est des
  393.     ; braves gars).
  394.  
  395.     mov  ax,Screen_width ; Vous devez indiquer à la routine quelle est la
  396.     shr  ax,3            ; largeur de l'écran
  397.     mov  ah,al
  398.     mov  al,13h
  399.     out  dx,ax
  400.  
  401.     mov  dx,3C4h     ; Maintenant vous avez la bonne résolution mais il peut
  402.     mov  ax,0F02h    ; y avoir des pixels pourris à l'écran à cause de zones
  403.     out  dx,ax       ; non nettoyées de la mémoire vidéo.
  404.     mov  edi,0A0000h ; Donc on va nettoyer la mémoire à partir de 0A0000h
  405.     xor  eax,eax     ; avec la valeur 0 (qui est le noir standard) et sur une
  406.     mov  ecx,4000h   ; longueur de 4000h dwords (256Ko).
  407.     rep  stosd       ; Allez, liquidez-moi tout ça!
  408.  
  409.  
  410.  
  411.   La table de constantes que vous devez employer est l'une des suivantes:
  412.   (Ces tables sont au format C, mais elles peuvent facilement êtres employées
  413.    dans d'autres langages)
  414.  
  415.   word X320Y224[] =
  416.     { 0x10E3, 0x6F06, 0xBA07, 0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0x0014,
  417.       0xC715, 0x0416, 0xE317, 0xE317 };
  418.   word X320Y240[] =
  419.     { 0x0AE3, 0x0D06, 0x3E07, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x0014, 0xE715,
  420.       0x0616, 0xE317 };
  421.   word X320Y256[] =
  422.     { 0x0CE3, 0x2306, 0xB207, 0x0008, 0x6109, 0x0A10, 0xAC11, 0xFF12, 0x2013,
  423.       0x0014, 0x0715, 0x1A16, 0xE317 };
  424.   word X320Y270[] =
  425.     { 0x0BE7, 0x3006, 0xF007, 0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x0014,
  426.       0x1F15, 0x2F16, 0xE317 };
  427.   word X320Y282[] =
  428.     { 0x0CE3, 0x6206, 0xF007, 0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x2F13,
  429.       0x0014, 0x3C15, 0x5C16, 0xE317 };
  430.   word X320Y300[] =
  431.     { 0x0DE3, 0x4606, 0x1F07, 0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x2013,
  432.       0x0014, 0x2F15, 0x4416, 0xE317 };
  433.   word X320Y360[] =
  434.     { 0x09E3, 0x4009, 0x8810, 0x8511, 0x6712, 0x2013, 0x0014, 0x6D15, 0xBA16,
  435.       0xE317 };
  436.   word X320Y400[] =
  437.     { 0x03E3, 0x4009, 0x0014, 0xE317 };
  438.   word X320Y448[] =
  439.     { 0x0BE3, 0x6F06, 0xBA07, 0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0x0014,
  440.       0xC715, 0x0416, 0xE317 };
  441.   word X320Y480[] =
  442.     { 0x0AE3, 0x0D06, 0x3E07, 0x4009, 0xEA10, 0xAC11, 0xDF12, 0x0014, 0xE715,
  443.       0x0616 , 0xE317};
  444.   word X320Y512[] =
  445.     { 0x0CE3, 0x2306, 0xB207, 0x0008, 0x6009, 0x0A10, 0xAC11, 0xFF12, 0x2013,
  446.       0x0014, 0x0715, 0x1A16, 0xE317 };
  447.   word X320Y540[] =
  448.     { 0x0BE7, 0x3006, 0xF007, 0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x0014,
  449.       0x1F15, 0x2F16, 0xE317 };
  450.   word X320Y564[] =
  451.     { 0x0CE7, 0x6206, 0xF007, 0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x2013,
  452.       0x0014, 0x3C15, 0x5C16, 0xE317 };
  453.   word X320Y600[] =
  454.     { 0x0BE7, 0xBE06, 0xF007, 0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x0014,
  455.       0x5815, 0x7016, 0xE317 };
  456.   word X360Y200[] =
  457.     { 0x08E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x0014, 0xE317 };
  458.   word X360Y224[] =
  459.     { 0x10E3, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6F06, 0xBA07,
  460.       0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0xC715, 0x0416, 0xE317 };
  461.   word X360Y240[] =
  462.     { 0x11E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x0D06, 0x3E07,
  463.       0x4109, 0xEA10, 0xAC11, 0xDF12, 0x2D13, 0x0014, 0xE715, 0x0616, 0xE317 };
  464.   word X360Y256[] =
  465.     { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x2B06, 0xB207,
  466.       0x0008, 0x6109, 0x0E10, 0xAC11, 0xFF12, 0x2D13, 0x0014, 0x0715, 0x1A16,
  467.       0xE317 };
  468.   word X360Y270[] =
  469.     { 0x10E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x3006, 0xF007,
  470.       0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x1F15, 0x2F16, 0xE317 };
  471.   word X360Y282[] =
  472.     { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6206, 0xF007,
  473.       0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x2F13, 0x0014, 0x3C15, 0x5C16,
  474.       0xE317 };
  475.   word X360Y300[] =
  476.     { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x4606, 0x1F07,
  477.       0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x2D13, 0x0014, 0x2F15, 0xE317,
  478.       0x4416 };
  479.   word X360Y360[] =
  480.     { 0x0FE7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x4009, 0x8810,
  481.       0x8511, 0x6712, 0x2D13, 0x0014, 0x6D15, 0xBA16, 0xE317 };
  482.   word X360Y400[] =
  483.     { 0x09E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x4009, 0x0014,
  484.       0xE317 };
  485.   word X360Y448[] =
  486.     { 0x10E3, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6F06, 0xBA07,
  487.       0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0xC715, 0x0416, 0xE317 };
  488.   word X360Y480[] =
  489.     { 0x11E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x0D06, 0x3E07,
  490.       0x4009, 0xEA10, 0xAC11, 0xDF12, 0x2D13, 0x0014, 0xE715, 0x0616, 0xE317 };
  491.   word X360Y512[] =
  492.     { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x2B06, 0xB207,
  493.       0x0008, 0x6009, 0x0E10, 0xAC11, 0xff12, 0x2D13, 0x0014, 0x0715, 0x1A16,
  494.       0xE317 };
  495.   word X360Y540[] =
  496.     { 0x10E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x3006, 0xF007,
  497.       0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x1F15, 0x2F16, 0xE317 };
  498.   word X360Y564[] =
  499.     { 0x12EB, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6206, 0xF007,
  500.       0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x2D13, 0x0014, 0x3C15, 0x5C16,
  501.       0xE317 };
  502.   word X360Y600[] =
  503.     { 0x10E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0xBE06, 0xF007,
  504.       0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x5815, 0x7016, 0xE317 };
  505.   word X400Y200[] =
  506.     { 0x08E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x0014, 0xE317 };
  507.   word X400Y224[] =
  508.     { 0x10E3, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6F06, 0xBA07,
  509.       0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0xC715, 0x0416, 0xE317 };
  510.   word X400Y240[] =
  511.     { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x0D06, 0x3E07,
  512.       0x0008, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x3213, 0x0014, 0xE715, 0x0616,
  513.       0xE317 };
  514.   word X400Y256[] =
  515.     { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x2B06, 0xB207,
  516.       0x0008, 0x6109, 0x1310, 0xAC11, 0xFF12, 0x3213, 0x0014, 0x0715, 0x1A16,
  517.       0xE317 };
  518.   word X400Y270[] =
  519.     { 0x10E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x3006, 0xF007,
  520.       0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x1F15, 0x2F16, 0xE317 };
  521.   word X400Y282[] =
  522.     { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6206, 0xF007,
  523.       0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x2F13, 0x0014, 0x3C15, 0x5C16,
  524.       0xE317 };
  525.   word X400Y300[] =
  526.     { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x4606, 0x1F07,
  527.       0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x3213, 0x0014, 0x2F15, 0x4416,
  528.       0xE317 };
  529.   word X400Y360[] =
  530.     { 0x0FE7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x4009, 0x8810,
  531.       0x8511, 0x6712, 0x3213, 0x0014, 0x6D15, 0xBA16, 0xE317 };
  532.   word X400Y400[] =
  533.     { 0x09E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x4009, 0x0014,
  534.       0xE317 };
  535.   word X400Y448[] =
  536.     { 0x10E3, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6F06, 0xBA07,
  537.       0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0xC715, 0x0416, 0xE317 };
  538.   word X400Y480[] =
  539.     { 0x11E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x0D06, 0x3E07,
  540.       0x4009, 0xEA10, 0xAC11, 0xDF12, 0x3213, 0x0014, 0xE715, 0x0616, 0xE317 };
  541.   word X400Y512[] =
  542.     { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x2B06, 0xB207,
  543.       0x0008, 0x6009, 0x1310, 0xAC11, 0xFF12, 0x3213, 0x0014, 0x0715, 0x1A16,
  544.       0xE317 };
  545.   word X400Y540[] =
  546.     { 0x10E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x3006, 0xF007,
  547.       0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x1F15, 0x2F16, 0xE317 };
  548.   word X400Y564[] =
  549.     { 0x12EB, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6206, 0xF007,
  550.       0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x3213, 0x0014, 0x3C15, 0x5C16,
  551.       0xE317 };
  552.   word X400Y600[] =
  553.     { 0x10E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0xBE06, 0xF007,
  554.       0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x5815, 0x7016, 0xE317 };
  555.  
  556.  
  557.   La structure: (exemple)
  558.  
  559.        ┌────Ceci est le nombre de valeurs à envoyer aux registres CRTC. C'est
  560.        │    en fait le nombre de words dans la table moins 1 (à cause du 1er
  561.        │    word de la table qui n'est pas envoyé au CRTC mais qui contient
  562.        │    une valeur à envoyer au registre MISCELLANEOUS et le nombre de
  563.        │    valeurs à envoyer aux registres CRTC ;) ).
  564.        │
  565.        │ ┌──Ceci est la valeur à envoyer au registre MISCELLANEOUS (ou 0 si
  566.        │ │  aucune valeur ne doit y être envoyée).
  567.        │ │
  568.        │ │     ┌───Ceci est une valeur à envoyer dans un registre du CRTC.
  569.        │ │     │
  570.        │ │     │ ┌─Ceci est le numéro du registre du CRTC qui recevra la
  571.        │ │     │ │ valeur citée précédemment.
  572.        ├┐├┐    ├┐├┐
  573.    { 0x0AE3, 0x0D06, 0x3E07, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x0014, 0xE715,
  574.      0x0616, 0xE317 };
  575.  
  576.     Vous pouvez remarquer que les registres 0 à 5 (et le 13h) du CRTC
  577.   définissent la largeur de l'écran, alors que les registres 6 à 17h (à
  578.   l'exception du 13h) definissent la hauteur de l'écran.
  579.  
  580.  
  581.     Nous avons plus de modes en poche que les quelques-uns :) que nous avons
  582.   inclus dans GrafX 2.00, mais ils ne sont ni vraiment utiles ni vraiment
  583.   stables. Nous pourrons toutefois décider de les inclure dans une prochaine
  584.   version si nous changeons la fenêtre de choix de résolution (une liste de
  585.   modes à la manière des sélecteurs de fichiers devrait constituer le
  586.   meilleur choix si l'on rajoute des modes vidéos puisqu'il n'y a plus de
  587.   place pour en loger d'autres :) ).
  588.     S'il manque certains de vos modes préféres, envoyez nous simplement la
  589.   liste des constantes que l'on doit balancer au CRTC à la manière de la
  590.   structure utilisée ci-dessus.
  591.  
  592.   IMPORTANT! Les valeurs des constantes citées plus haut ne sont pas
  593.              supportées par tous les moniteurs ou les cartes vidéos.
  594.              Nous avons testé GrafX2 avec différentes configurations et avons
  595.              constatés que certains modes ne marchent pas du tout avec
  596.              certaines cartes vidéos, alors que d'autres débordent de l'écran,
  597.              sont décentrés, assombris, trop clairs, ou tassés.
  598.              Toutefois, ils marchent tous correctement avec notre pauvre
  599.              petite Tseng Labs ET4000...
  600.  
  601.   Si vous avez déjà une bonne connaissance à propos des Modes X, et avez des
  602.   valeurs différentes des notres pour certains modes, merci de nous en
  603.   informer. Nous nous en servirons s'ils marchent mieux sur une majorité
  604.   d'ordinateurs.
  605.  
  606.  
  607.  
  608. VESA: (Un "pseudo-standard" pour les modes Super-VGA)
  609. ═════
  610.  
  611.     Nous nous servons du VESA pour des modes qui nécessittent une largeur de
  612.   640, 800 ou 1024 pixels. Mais il existe un moyen de combiner la hauteur des
  613.   Modes X avec les modes VESA, il est ainsi possible d'avoir des modes aussi
  614.   timbrés qu'en Mode X.
  615.  
  616.  
  617.   mov  ax,4F02h
  618.   mov  bx,Video_mode
  619.   int  10h
  620.  
  621.  
  622.   Les modes VESA 256 couleur VESA sont:
  623.     100h :  640x400
  624.     101h :  640x480
  625.     103h :  800x600
  626.     105h : 1024x768
  627.     107h : 1280x1024 (non disponible dans GrafX2 parce qu'uniquement supporté
  628.                      par des cartes vidéo avec 2 Megaoctets ou plus de mémoire
  629.                      vidéo)
  630.  
  631.  
  632.   Comme avec les Modes X, vous pouvez modifier les registres CRTC pour accéder
  633.   aux modes "VESA-X"! (Notez que certaines cartes vidéo ne supportent pas les
  634.   modifications des registres du CRTC VGA dans les modes VESA.)
  635.  
  636.  
  637.   Pour passer dans ces modes étendus, passez dans un mode VESA standard ayant
  638.   la bonne largeur, puis appelez Modif_registres_CRTC avec la bonne table de
  639.   hauteur.
  640.  
  641.   Exemple (640x512) :
  642.     VESA_Set_mode(101h)         // On passe dans un mode qui a la même largeur
  643.     Modif_registres_CRTC(Y512)  // On modifie la hauteur
  644.  
  645.  
  646.   * Tables des hauteurs:
  647.  
  648.   word Y256[] =
  649.    { 0x0900, 0x2B06, 0xB207, 0x0008, 0x6109, 0x0A10, 0xAC11, 0xFF12, 0x0715,
  650.      0x1A16 };
  651.  
  652.   word Y350[] =
  653.    { 0x09A3, 0xBF06, 0x1F07, 0x0008, 0x4009, 0x8310, 0x8511, 0x5D12, 0x6315,
  654.      0xBA16 };
  655.  
  656.   word Y512[] =
  657.    { 0x0900, 0x2B06, 0xB207, 0x0008, 0x6009, 0x0A10, 0xAC11, 0xFF12, 0x0715,
  658.      0x1A16 };
  659.  
  660.   word Y564[] =
  661.    { 0x09E7, 0x6206, 0xF007, 0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x3C15,
  662.      0x5C16 };
  663.  
  664.  
  665.  
  666.   Modifier les registres CRTC: (inspiré de l'init. des Modes X... voir plus
  667.   ────────────────────────────  haut pour de plus amples détails)
  668.  
  669.   mov  esi,XVESA_Ptr
  670.   cld
  671.  
  672.   lodsb
  673.   or   al,al       ; Devons nous modifier le mode vidéo de base ?
  674.   jz   NonMerci    ; Non?─┐ La réponse peut être "Non" car les initialisations
  675.   mov  dx,3C2h     ;      │ de certains modes VESA mettent directement la
  676.   out  dx,al       ;      │ bonne valeur pour le registre MISCELLANEOUS.
  677.   NonMerci:        ; <────┘
  678.  
  679.   mov  dx,3D4h
  680.   mov  al,11h
  681.   out  dx,al
  682.   inc  dx
  683.   in   al,dx
  684.   and  al,7Fh
  685.   out  dx,al
  686.  
  687.   dec  dx
  688.   lodsb
  689.   xor  ecx,ecx
  690.   mov  cl,al
  691.   rep  outsw
  692.  
  693.  
  694.  
  695.     Si vous êtes suffisament astucieux, vous pourrez combiner les constantes
  696.   utilisées dans les Modes X pour obtenir plus de modes "VESA-X" tels que le
  697.   640x200, 800x480, etc... (mais je ne pense pas que ça marche convenablement
  698.   avec les largeurs de 1024 pixels puisque ce mode est généralement
  699.   entrelacé... Mais qui sait?...)
  700.     Je pense que le plus difficile est de trouver la bonne valeur du registre
  701.   MISCELLANEOUS.
  702.