ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³°±²Û Doc. technique pour GrafX 2.00 - Version 1.08 (5 octobre 1997) Û²±°³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Ce fichier traite: - du format d'image PKM - des valeurs … envoyer au CRTC pour avoir accŠs … tous les modes vid‚os incroyables disponibles dans GrafX 2.00 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ °±²Û Le format d'image PKM - par Karl Maritaud Û²±° ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Tout d'abord, je tiens a dire que j'ai cr‚‚ ce format il y a d‚j… quelques ann‚es, … l'‚poque o— je ne savais pas comment charger les meilleurs formats (GIF par exemple) et que je voulais ‚galement avoir mon propre format. Le format PKM a ‚t‚ con‡u pour ˆtre trŠs simple, facile … encoder et … d‚coder. De plus, son header est trŠs simple (court) et evolutif. Le seul vrai d‚faut que je puisse y trouver est que l'on ne peut sauver des images qu'en 256 couleurs. Je sais que vous allez vous dire: "Oh non! Encore un nouveau format … la con! J'm'en servirai jamais! En plus le taux de compression est naze! Je prefŠre le GIF!". Et je r‚pondrai: "Ouais! T'as raison. Mais si tu ne sais pas comment charger du GIF et que tu veux un format simple avec une compression correcte (du moins sur les images simples), il peut ˆtre utile." Donc, voici la documentation de ce format... Le HEADER: ÍÍÍÍÍÍÍÍÍÍ Le header est la structure de 780 octets suivante. (Ne vous inqui‚tez pas … propos de la taille. C'est tout simplement parce que la palette fait partie du header). ÚÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Pos ³ Champ ³ Type ³Taille³ Description ³ ÆÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵ ³ 0 ³ Signature ³ char ³ 3 ³ ChaŒne constante "PKM" (SANS d‚limitation³ ³ ³ ³ ³ ³ de taille '\0' ou autres...) ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 3 ³ Version ³ byte ³ 1 ³ Pour le moment, ce champ ne peut prendre ³ ³ ³ ³ ³ ³ que la valeur 0. ³ ³ ³ ³ ³ ³ D'autres m‚thodes de compression pourront³ ³ ³ ³ ³ ³ la modifier mais pour l'instant il n'y en³ ³ ³ ³ ³ ³ a qu'une seule. ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 4 ³ Pack_byte ³ byte ³ 1 ³ Valeur de l'octet de reconnaissance pour ³ ³ ³ ³ ³ ³ les r‚p‚titions de couleurs cod‚es sur 1 ³ ³ ³ ³ ³ ³ Octet. (Voir la section sur la m‚thode de³ ³ ³ ³ ³ ³ compression pour plus d'informations) ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 5 ³ Pack_word ³ byte ³ 1 ³ Valeur de l'octet de reconnaissance pour ³ ³ ³ ³ ³ ³ les r‚p‚titions de couleurs cod‚es sur 2 ³ ³ ³ ³ ³ ³ Octets. (Voir la section sur la m‚thode ³ ³ ³ ³ ³ ³ de compression pour plus d'informations) ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 6 ³ Largeur ³ word ³ 2 ³ Largeur de l'image (en pixels) ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 8 ³ Hauteur ³ word ³ 2 ³ Hauteur de l'image (en pixels) ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 10 ³ Palette ³ byte ³ 768 ³ Palette RGB (RGB RGB ... 256 fois) avec ³ ³ ³ ³ ³ ³ des valeurs de 0 … 63. Je sais que le ³ ³ ³ ³ ³ ³ standard dans les fichiers d'images est ³ ³ ³ ³ ³ ³ de 0 … 255 mais je trouve ‡a cr‚tin! ³ ³ ³ ³ ³ ³ C'est tellement plus simple d'envoyer la ³ ³ ³ ³ ³ ³ palette toute entiŠre dans le port 3C9h ³ ³ ³ ³ ³ ³ avec un REP OUTSB sans avoir … convertir ³ ³ ³ ³ ³ ³ la palette. ³ ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ 778 ³ Taille_PH ³ word ³ 2 ³ Taille du Post-header. C'est le nombre ³ ³ ³ ³ ³ ³ d'octets entre le header et les donn‚es ³ ³ ³ ³ ³ ³ de l'image. Cette valeur peut valoir 0. ³ ÀÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Les donn‚es du type "word" sont stock‚es selon les conventions d'Intel: c'est-…-dire l'octet de poids le plus faible en premier. Le POST-HEADER: ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ Le post-header a une taille variable. Il a ‚t‚ con‡u pour supporter les nouvelles fonctions de ce format sans avoir a changer complŠtement le format. Il est constitu‚ d'identificateurs de champ suivis par leur taille et leur contenu. Un identificateur de champ est cod‚ sur 1 octet ainsi que sa taille. Ces identificateurs de champ sont: (cette liste peut ˆtre rallong‚e...) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 : Commentaire sur l'image 1 : Dimensions de l'‚cran d'origine 2 : Couleur de fond (couleur de transparence) Si vous rencontrez un champ inconnu par votre routine de chargment, sautez simplement au del…. Mais, par contre, si un champ vous dit de sauter … une position qui tombe aprŠs le d‚but th‚orique des donn‚es de l'image, alors c'est qu'il y a une erreur dans le fichier. Les champs: ÄÄÄÄÄÄÄÄÄÄÄ * Commentaire: Grƒce … ce champ, les artistes vont pouvoir commenter leurs dessins. Notez que GrafX 2 a une taille limite de commentaire de 32 caractŠres. Mais vous pourrez avoir des commentaires allant jusqu'… 255 caractŠres si vous cr‚ez votre propre viewer puisque GrafX 2 ignorera simplement les caractŠres en trop. Exemple: [0],[15],[Dessin de X-Man] Cette s‚quence signifie: - le champ est un commentaire - le commentaire a une taille de 15 caractŠres (il n'y a pas de caractŠre de fin de chaŒne puisque vous connaissez sa taille) - le commentaire est "Dessin de X-Man" * Dimensions de l'‚cran d'origine: Puisque GrafX 2 propose un ‚norme choix de r‚solutions, il a sembl‚ pratique d'ajouter un champ indicant quelles ‚taient les dimensions de l'‚cran d'origine. Exemple: [1],[4],[320],[256] Cette s‚quence signifie: - Le champ d‚crit les dimensions de l'‚cran d'origine - Les dimensions sont 2 words (donc cette valeur doit ˆtre ‚gale … 4) - La largeur de l'‚cran d'origine ‚tait de 320 pixels - La hauteur de l'‚cran d'origine ‚tait de 256 pixels Notez que les words stock‚s dans les champs sont ‚crits … la maniŠre Intel. La BETA-version 90% ne respectait pas cette norme (d‚sol‚). Ce n'est pas bien grƒve mais les images sauv‚es avec la version 90% et recharg‚es avec une version post‚rieure (91% et plus) ne passeront pas dans la bonne r‚solution. * Couleur de fond: Enregistrer la couleur de fond (couleur de transparence) se r‚veille particuliŠrement utile lorsque vous voulez sauvegarder une brosse. La taille de ce champ est 1 octet (indice de la couleur entre 0 et 255). Exemple: [2],[1],[255] Cette s‚quence signifie: - le champ d‚crit la couleur de fond - la valeur prend 1 octet - La couleur de transparence est 255 La METHODE DE COMPACTAGE DE L'IMAGE: ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ La m‚thode de compression PKM est une sorte de "Run-Length-Compression" qui est trŠs efficace sur les images comportant de longues r‚p‚titions d'une mˆme couleur horizontalement. En fait la compression commence … ˆtre efficace s'il y a souvent plus de 3 fois la mˆme color cons‚cutivement. Je pense qu'il est pr‚f‚rable de vous donner directement l'algorithme plut“t que de nager dans des explications incomprehensibles. DEBUT /* fonctions: Lire_octet(Fichier) Lit et retourne 1 octet … partir de Fichier Dessiner_pixel(X,Y,Couleur) Dessine un pixel d'une certaine Couleur … la position (X,Y) Taille_fichier(Fichier) Retourne la taille totale d'un Fichier en octets variables: le type de Taille_image est dword le type de Taille_donnees est dword le type de Compteur_donnees est dword le type de Compteur_pixels est dword le type de Couleur est byte le type de Octet_lu est byte le type de Word_lu est word le type de Compteur est word le type de Fichier est */ /* A cet endroit, le header et le post-header ont d‚j… ‚t‚ lus. */ Taille_image <- Header.Largeur * Header.Hauteur Taille_donnees <- Taille_fichier(Fichier) - (780+Header.Taille_PH) Compteur_donnees <- 0 Compteur_pixels <- 0 /* Boucle de d‚compression: */ TANT QUE ((Compteur_pixelsHeader.Pack_byte) ET (Octet_lu<>Header.Pack_word)) ALORS { Dessiner_pixel(Compteur_pixels MOD Header.Largeur, Compteur_pixels DIV Header.Largeur, Octet_lu) Compteur_pixels <- Compteur_pixels + 1 Compteur_donnees <- Compteur_donnees + 1 } SINON /* Est-ce que le nombre de pixels … r‚p‚ter est cod‚... */ { /* ... sur 1 octet ? */ SI (Octet_lu = Header.Pack_byte) ALORS { Couleur <- Lire_octet(Fichier) Octet_lu <- Lire_octet(Fichier) POUR Compteur ALLANT DE 0 A (Octet_lu-1) PAR PAS DE +1 Dessiner_pixel((Compteur_pixels+Compteur) MOD Header.Largeur, (Compteur_pixels+Compteur) DIV Header.Largeur, Couleur) Compteur_pixels <- Compteur_pixels + Octet_lu Compteur_donnees <- Compteur_donnees + 3 } SINON /* ... sur 2 octets ? */ { Couleur <- Lire_octet(Fichier) Word_lu <- (word) (Lire_octet(Fichier) SHL 8)+Lire_octet(Fichier) POUR Compteur ALLANT DE 0 A (Word_lu-1) PAR PAS DE +1 Dessiner_pixel((Compteur_pixels+Compteur) MOD Header.Largeur, (Compteur_pixels+Compteur) DIV Header.Largeur, Couleur) Compteur_pixels <- Compteur_pixels + Word_lu Compteur_donnees <- Compteur_donnees + 4 } } } FIN Par exemple, la s‚quence suivante: (on suppose que Pack_byte=01 et Pack_word=02) 04 03 01 05 06 03 02 00 01 2C sera d‚cod‚e comme: 04 03 05 05 05 05 05 05 03 00 00 00 ... (rep‚ter 0 300 fois (012Ch=300)) Les r‚p‚titions qui tiennent sur un word doivent ˆtre ‚crites avec leur octet de poids le plus fort en premier. Je sais que ‡a va … l'encontre du standard Intel mais puisque je lis les octets du fichier au travers d'un buffer (franchement plus rapide), Je me fous complŠtement de l'ordre (D‚sol‚ :)). Mais les words du header et du post-header doivent ˆtre ‚crits et lus … la maniŠre Intel! Conseils de compactage: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ * Comme vous pouvez le constater, il pourrait y avoir un problŠme lorsque vous devriez compacter un pixel brut de couleur ‚gale … Pack_byte ou … Pack_word. Ces pixels doivent toujours ˆtre cod‚s comme des paquets mˆme s'il n'y a qu'un seul pixel. Exemple: (supposons que Pack_byte=9) 9 sera encod‚ 9,9,1 (Le 1er 9 dans la s‚quence... 9,9 sera encod‚ 9,9,2 ... encod‚e est Pack_byte) etc... * Il semble ‚vident de trouver des valeurs pour Pack_byte et Pack_word qui ne sont jamais (ou presque) utilis‚es. Donc, une petite routine qui trouve les 2 couleurs les moins utilis‚es dans l'image devrait ˆtre appel‚e avant avant de commencer la compression. Ceci peut ˆtre r‚alis‚ presque instanta- n‚ment en Assembleur. * Quand vous voulez ‚crire une s‚quence de 2 couleurs identiques, ‚crivez simplement ces 2 couleurs l'une aprŠs l'autre (Couleur,Couleur) puisque ‡a ne prend que 2 octets au lieu de 3 si vous aviez ‚crit un paquet (Pack_byte, Couleur,2). * Si vous compressez une image extrˆmement simple qui comporte une s‚quence de plus de 65535 fois la mˆme couleur cons‚cutivement, vous devez "casser" la s‚quence et continuer avec un nouveau paquet. Exemple: vous devez compacter les 65635 mˆmes octets cons‚cutifs (de couleur 0 par exemple) (On suppose que Pack_byte=01 et Pack_word=02) Vous devrez alors ‚crire: 02 00 FF FF 01 00 64 (FFFFh=65535, 64h=100) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ °±²Û Passer dans les modes vid‚os de GrafX 2.00 Û²±° ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Toutes les proc‚dures d'initialisation de mode sont ‚crites en ASM 386. De toutes fa‡ons, si vous ne comprenez pas une ligne d'ASM, je ne vois vraiment pas … quoi pourront vous servir ces proc‚dures. Elles ont ‚t‚ con‡ues pour ˆtre utilis‚es dans le modŠle de m‚moire FLAT. Mais cela ne devrait pas vous prendre trop de temps de les adapter au modŠle que vous souhaitez utiliser puisqu'il n'y a que les manipulations de m‚moire que cela affectera (utilisez donc DS:SI au lieu de ESI, ES:DI … la place de EDI et faŒtes attention … l'adresse 0A0000h qui se transforme en l'adresse 0A000h:0000h). MCGA: (Mode VGA standard) ÍÍÍÍÍ Y-a-t'il quelqu'un sur cette planŠte qui ne sache toujours pas comment on passe en mode MCGA 320x200 en 256 couleurs ??!? Bon... Je suppose que vous ˆtes un novice si vous lisez les 2 lignes suivantes :) mov ax,0013h int 10h Modes X: (Modes VGA ‚tendus) ÍÍÍÍÍÍÍÍ Bon... Il me semble que le Mode X original ‚tait en 320x240, mais maintenant tout le monde appelle "Modes X" (ou X-Modes, ou Tweaked modes) tous les modes VGA qui utilise plus de 64Ko de m‚moire vid‚o et la structure "Unchained". Afficher un pixel dans n'importe quel Mode X peut ˆtre effectu‚ par la mˆme et unique fonction (mais je ne vous expliquerai pas comment faire, il vous suffit d'indiquer … la fonction la taille des plans (Largeur/4)). Si vous ne comprenez rien … ce que je dis, (Unchained, plans...) il vous suffit de lire n'importe quelle bonne documentation sur le Mode X. Nous tenons … remercier les auteurs de XLIB2 pour nous avoir ‚conomis‚ du temps en ayant ‚crit cette fonction. Nous l'avons l‚gŠrement optimis‚e en fonction de nos besoins, mais l'essentiel en a ‚t‚ conserv‚. mov ax,13h ; Oui! Encore le mode MCGA! Tous les Modes X doivent int 10h ; commencer … partir du mode VGA standard, mais bien des ; choses changent par la suite. mov dx,3C6h ; Pour la dur‚e de l'initialisation, on va ‚teindre la xor al,al ; palette de fa‡on … ce que l'utilisateur ne subisse pas out dx,al ; nos triturations. mov dx,3C4h ; Nous allons demander au registre TIMING SEQUENCER de mov ax,0604h ; passer dans le mode "Unchained" (mode X), sans g‚rer de out dx,ax ; parit‚, et un accŠs aux 256Ko de la carte vid‚o. mov ax,0100h ; On va ensuite enclencher le reset synchrone du registre out dx,ax ; TS car on s'apprˆte … jouer avec les registres. mov al,01h ; De la mˆme fa‡on que pour la palette, on demande … la out dx,al ; carte vid‚o de ne plus scruter la m‚moire pour inc dx ; afficher son contenu. Ainsi, c'est une fa‡on de plus in al,dx ; d'‚viter l'affichage parasite qui arrive le temps que mov ah,al ; le mode soit totalement initialis‚ et stabilis‚. mov al,01h ; De plus, on peut esp‚rer qu'en demandant un arrˆt de push ax ; la lecture de la m‚moire, le systŠme s'en voit un peu mov al,ah ; acc‚l‚r‚, et ainsi acc‚l‚rer l'initialisation du mode or al,20h ; graphique (l'espoir fait vivre :)) out dx,al ; mov esi,X_ptr ; Pointeur sur la liste des constantes … envoyer au CRTC. cld lodsb ; Ceci charge dans AL une valeur qui nous dira quoi faire ; avec le registre MISCELLANEOUS, et incr‚mente ESI. ; La valeur est ‚gale … ZERO => Rien … faire ; sinon => Envoyer AL au reg. MISC. or al,al ; Devons nous modifier le mode vid‚o de base ? jz NonMerci ; Non?Ä¿ En fait, la r‚ponse est toujours "Oui". mov dx,3C2h ; ³ Sauf pour quelques modes tels que le out dx,al ; ³ 320x200 en Mode X NonMerci: ; <ÄÄÄÄÙ (mais notre mode 320x200 est en MCGA...) mov dx,3C4h ; On en a termin‚ avec les manipulations du registre mov ax,0300h ; MISCELLANEOUS, on peut maintenant d‚senclencher le out dx,ax ; reset synchrone du registre TIMING SEQUENCER. ; Et maintenant, si on jouait avec le CRTC? mov dx,3D4h ; Dans le 18Šme registre du CRTC, on va d‚senclencher le mov al,11h ; bit de protection. Sans cela, les valeurs que nous out dx,al ; aurions envoy‚es aux registres du CRTC auraient ‚t‚ inc dx ; ignor‚es. in al,dx and al,7Fh out dx,al dec dx ; DX pointe … nouveau sur "l'entr‚e" du registre CRTC. lodsb ; Ceci met dans AL le nombre de registres CRTC … changer xor ecx,ecx ; On doit nettoyer ECX avant de commencer … r‚p‚ter... mov cl,al ; ...CL (AL) fois OUTSW rep outsw ; On peut envoyer la sauce aux registres du CRTC! ; Juste au cas o— le 20Šme registre CRTC aurait ‚t‚ oubli‚ dans la table ; d'initialisation, on peut le calculer nous-mˆmes (Ouaip, on est des ; braves gars). mov ax,Screen_width ; Vous devez indiquer … la routine quelle est la shr ax,3 ; largeur de l'‚cran mov ah,al mov al,13h out dx,ax mov dx,3C4h ; Maintenant vous avez la bonne r‚solution mais il peut mov ax,0F02h ; y avoir des pixels pourris … l'‚cran … cause de zones out dx,ax ; non nettoy‚es de la m‚moire vid‚o. mov edi,0A0000h ; Donc on va nettoyer la m‚moire … partir de 0A0000h xor eax,eax ; avec la valeur 0 (qui est le noir standard) et sur une mov ecx,4000h ; longueur de 4000h dwords (256Ko). rep stosd ; Allez, liquidez-moi tout ‡a! mov dx,3C4h ; On peut redemander … la carte VGA de relire la m‚moire pop ax ; pour afficher l'‚cran... out dx,ax ; mov dx,3C6h ; ... et r‚tablir la palette pour que l'image soit mov al,0FFh ; visible … l'utilisateur. out dx,al ; La table de constantes que vous devez employer est l'une des suivantes: (Ces tables sont au format C, mais elles peuvent facilement ˆtres employ‚es dans d'autres langages) word X320Y224[] = { 0x0BA3, 0x6F06, 0xBA07, 0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0x0014, 0xC715, 0x0416, 0xE317 }; word X320Y240[] = { 0x0AE3, 0x0D06, 0x3E07, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x0014, 0xE715, 0x0616, 0xE317 }; word X320Y256[] = { 0x0CE3, 0x2306, 0xB207, 0x0008, 0x6109, 0x0A10, 0xAC11, 0xFF12, 0x2013, 0x0014, 0x0715, 0x1A16, 0xE317 }; word X320Y270[] = { 0x0BE7, 0x3006, 0xF007, 0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x0014, 0x1F15, 0x2F16, 0xE317 }; word X320Y282[] = { 0x0CE3, 0x6206, 0xF007, 0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x2F13, 0x0014, 0x3C15, 0x5C16, 0xE317 }; word X320Y300[] = { 0x0DE3, 0x4606, 0x1F07, 0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x2013, 0x0014, 0x2F15, 0x4416, 0xE317 }; word X320Y360[] = { 0x09E3, 0x4009, 0x8810, 0x8511, 0x6712, 0x2013, 0x0014, 0x6D15, 0xBA16, 0xE317 }; word X320Y400[] = { 0x03E3, 0x4009, 0x0014, 0xE317 }; word X320Y448[] = { 0x0BA3, 0x6F06, 0xBA07, 0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0x0014, 0xC715, 0x0416, 0xE317 }; word X320Y480[] = { 0x0AE3, 0x0D06, 0x3E07, 0x4009, 0xEA10, 0xAC11, 0xDF12, 0x0014, 0xE715, 0x0616 , 0xE317}; word X320Y512[] = { 0x0CE3, 0x2306, 0xB207, 0x0008, 0x6009, 0x0A10, 0xAC11, 0xFF12, 0x2013, 0x0014, 0x0715, 0x1A16, 0xE317 }; word X320Y540[] = { 0x0BE7, 0x3006, 0xF007, 0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x0014, 0x1F15, 0x2F16, 0xE317 }; word X320Y564[] = { 0x0CE7, 0x6206, 0xF007, 0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x2013, 0x0014, 0x3C15, 0x5C16, 0xE317 }; word X320Y600[] = { 0x0BE7, 0xBE06, 0xF007, 0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x0014, 0x5815, 0x7016, 0xE317 }; word X360Y200[] = { 0x09E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x2D13, 0x0014, 0xE317 }; word X360Y224[] = { 0x12A7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6F06, 0xBA07, 0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0x2D13, 0x0014, 0xC715, 0x0416, 0xE317 }; word X360Y240[] = { 0x11E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x0D06, 0x3E07, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x2D13, 0x0014, 0xE715, 0x0616, 0xE317 }; word X360Y256[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x2B06, 0xB207, 0x0008, 0x6109, 0x0E10, 0xAC11, 0xFF12, 0x2D13, 0x0014, 0x0715, 0x1A16, 0xE317 }; word X360Y270[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x3006, 0xF007, 0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x2D13, 0x0014, 0x1F15, 0x2F16, 0xE317 }; word X360Y282[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6206, 0xF007, 0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x2D13, 0x0014, 0x3C15, 0x5C16, 0xE317 }; word X360Y300[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x4606, 0x1F07, 0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x2D13, 0x0014, 0x2F15, 0x4416, 0xE317 }; word X360Y360[] = { 0x0FE7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x4009, 0x8810, 0x8511, 0x6712, 0x2D13, 0x0014, 0x6D15, 0xBA16, 0xE317 }; word X360Y400[] = { 0x0AE7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x4009, 0x2D13, 0x0014, 0xE317 }; word X360Y448[] = { 0x12A7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6F06, 0xBA07, 0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0x2D13, 0x0014, 0xC715, 0x0416, 0xE317 }; word X360Y480[] = { 0x11E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x0D06, 0x3E07, 0x4009, 0xEA10, 0xAC11, 0xDF12, 0x2D13, 0x0014, 0xE715, 0x0616, 0xE317 }; word X360Y512[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x2B06, 0xB207, 0x0008, 0x6009, 0x0E10, 0xAC11, 0xff12, 0x2D13, 0x0014, 0x0715, 0x1A16, 0xE317 }; word X360Y540[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x3006, 0xF007, 0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x2D13, 0x0014, 0x1F15, 0x2F16, 0xE317 }; word X360Y564[] = { 0x12EB, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0x6206, 0xF007, 0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x2D13, 0x0014, 0x3C15, 0x5C16, 0xE317 }; word X360Y600[] = { 0x12E7, 0x6B00, 0x5901, 0x5A02, 0x8E03, 0x5E04, 0x8A05, 0xBE06, 0xF007, 0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x2D13, 0x0014, 0x5815, 0x7016, 0xE317 }; word X400Y200[] = { 0x09E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x3213, 0x0014, 0xE317 }; word X400Y224[] = { 0x12A7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6F06, 0xBA07, 0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0x3213, 0x0014, 0xC715, 0x0416, 0xE317 }; word X400Y240[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x0D06, 0x3E07, 0x0008, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x3213, 0x0014, 0xE715, 0x0616, 0xE317 }; word X400Y256[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x2B06, 0xB207, 0x0008, 0x6109, 0x1310, 0xAC11, 0xFF12, 0x3213, 0x0014, 0x0715, 0x1A16, 0xE317 }; word X400Y270[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x3006, 0xF007, 0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x3213, 0x0014, 0x1F15, 0x2F16, 0xE317 }; word X400Y282[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6206, 0xF007, 0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x3213, 0x0014, 0x3C15, 0x5C16, 0xE317 }; word X400Y300[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x4606, 0x1F07, 0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x3213, 0x0014, 0x2F15, 0x4416, 0xE317 }; word X400Y360[] = { 0x0FE7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x4009, 0x8810, 0x8511, 0x6712, 0x3213, 0x0014, 0x6D15, 0xBA16, 0xE317 }; word X400Y400[] = { 0x0AE7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x4009, 0x3213, 0x0014, 0xE317 }; word X400Y448[] = { 0x12A7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6F06, 0xBA07, 0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0x3213, 0x0014, 0xC715, 0x0416, 0xE317 }; word X400Y480[] = { 0x11E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x0D06, 0x3E07, 0x4009, 0xEA10, 0xAC11, 0xDF12, 0x3213, 0x0014, 0xE715, 0x0616, 0xE317 }; word X400Y512[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x2B06, 0xB207, 0x0008, 0x6009, 0x1310, 0xAC11, 0xFF12, 0x3213, 0x0014, 0x0715, 0x1A16, 0xE317 }; word X400Y540[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x3006, 0xF007, 0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x3213, 0x0014, 0x1F15, 0x2F16, 0xE317 }; word X400Y564[] = { 0x12EB, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0x6206, 0xF007, 0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x3213, 0x0014, 0x3C15, 0x5C16, 0xE317 }; word X400Y600[] = { 0x12E7, 0x7100, 0x6301, 0x6402, 0x9203, 0x6604, 0x8205, 0xBE06, 0xF007, 0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x3213, 0x0014, 0x5815, 0x7016, 0xE317 }; La structure: (exemple) ÚÄÄÄÄCeci est le nombre de valeurs … envoyer aux registres CRTC. C'est ³ en fait le nombre de words dans la table moins 1 (… cause du 1er ³ word de la table qui n'est pas envoy‚ au CRTC mais qui contient ³ une valeur … envoyer au registre MISCELLANEOUS et le nombre de ³ valeurs … envoyer aux registres CRTC ;) ). ³ ³ ÚÄÄCeci est la valeur … envoyer au registre MISCELLANEOUS (ou 0 si ³ ³ aucune valeur ne doit y ˆtre envoy‚e). ³ ³ ³ ³ ÚÄÄÄCeci est une valeur … envoyer dans un registre du CRTC. ³ ³ ³ ³ ³ ³ ÚÄCeci est le num‚ro du registre du CRTC qui recevra la ³ ³ ³ ³ valeur cit‚e pr‚c‚demment. ÿÿ ÿÿ { 0x0AE3, 0x0D06, 0x3E07, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0x0014, 0xE715, 0x0616, 0xE317 }; Vous pouvez remarquer que les registres 0 … 5 (et le 13h) du CRTC d‚finissent la largeur de l'‚cran, alors que les registres 6 … 17h (… l'exception du 13h) definissent la hauteur de l'‚cran. Nous avons plus de modes en poche que les quelques-uns :) que nous avons inclus dans GrafX 2.00, mais ils ne sont ni vraiment utiles ni vraiment stables. Nous pourrons toutefois d‚cider de les inclure dans une prochaine version. S'il manque certains de vos modes pr‚f‚res, envoyez nous simplement la liste des constantes que l'on doit balancer au CRTC … la maniŠre de la structure utilis‚e ci-dessus. IMPORTANT! Les valeurs des constantes cit‚es plus haut ne sont pas support‚es par tous les moniteurs ou les cartes vid‚os. Nous avons test‚ GrafX2 avec diff‚rentes configurations et avons constat‚s que certains modes ne marchent pas du tout avec certaines cartes vid‚os, alors que d'autres d‚bordent de l'‚cran, sont d‚centr‚s, assombris, trop clairs, ou tass‚s. Toutefois, ils marchent tous correctement avec notre pauvre petite Tseng Labs ET4000... Si vous avez d‚j… une bonne connaissance … propos du CRTC, et avez des valeurs diff‚rentes des notres pour certains modes, merci de nous en informer. Nous nous en servirons s'ils marchent mieux sur une majorit‚ d'ordinateurs. VESA: (Un "pseudo-standard" pour les modes Super-VGA) ÍÍÍÍÍ Nous nous servons du VESA pour des modes qui n‚cessitent une largeur de 640, 800 ou 1024 pixels. Mais il existe un moyen de combiner la hauteur des Modes X avec les modes VESA, il est ainsi possible d'avoir des modes aussi timbr‚s qu'en Mode X. mov ax,4F02h mov bx,Video_mode int 10h Les modes VESA 256 couleur VESA sont: 100h : 640x400 101h : 640x480 103h : 800x600 105h : 1024x768 107h : 1280x1024 (non disponible dans GrafX2 parce qu'uniquement support‚ par des cartes vid‚o avec 2 Megaoctets ou plus de m‚moire vid‚o) Comme avec les Modes X, vous pouvez modifier les registres CRTC pour acc‚der aux modes "VESA-X"! (Notez que certaines cartes vid‚o ne supportent pas les modifications des registres du CRTC VGA dans les modes VESA.) Pour passer dans ces modes ‚tendus, passez dans un mode VESA standard ayant la bonne largeur, puis appelez Modif_registres_CRTC avec la bonne table de hauteur. Exemple (640x512) : VESA_Set_mode(101h) // On passe dans un mode qui a la mˆme largeur Modif_registres_CRTC(Y512) // On modifie la hauteur * Tables des hauteurs: word Y224[] = { 0x09A3, 0x6F06, 0xBA07, 0x0008, 0x4109, 0x0810, 0x8A11, 0xBF12, 0xC715, 0x0416 }; word Y240[] = { 0x09E3, 0x0D06, 0x3E07, 0x0008, 0x4109, 0xEA10, 0xAC11, 0xDF12, 0xE715, 0x0616 }; word Y256[] = { 0x0900, 0x2B06, 0xB207, 0x0008, 0x6109, 0x0A10, 0xAC11, 0xFF12, 0x0715, 0x1A16 }; word Y270[] = { 0x09E7, 0x3006, 0xF007, 0x0008, 0x6109, 0x2010, 0xA911, 0x1B12, 0x1F15, 0x2F16 }; word Y282[] = { 0x0AE3, 0x6206, 0xF007, 0x0008, 0x6109, 0x310F, 0x3710, 0x8911, 0x3312, 0x3C15, 0x5C16 }; word Y300[] = { 0x09E3, 0x4606, 0x1F07, 0x0008, 0x4009, 0x3110, 0x8011, 0x2B12, 0x2F15, 0x4416 }; word Y350[] = { 0x09A3, 0xBF06, 0x1F07, 0x0008, 0x4009, 0x8310, 0x8511, 0x5D12, 0x6315, 0xBA16 }; word Y360[] = { 0x07E3, 0x0008, 0x4009, 0x8810, 0x8511, 0x6712, 0x6D15, 0xBA16 }; word Y400[] = { 0x01E3, 0x4009 }; word Y448[] = { 0x09A3, 0x6F06, 0xBA07, 0x0008, 0x4009, 0x0810, 0x8A11, 0xBF12, 0xC715, 0x0416 }; word Y480[] = { 0x09E3, 0x0D06, 0x3E07, 0x0008, 0x4009, 0xEA10, 0xAC11, 0xDF12, 0xE715, 0x0616 }; word Y512[] = { 0x0900, 0x2B06, 0xB207, 0x0008, 0x6009, 0x0A10, 0xAC11, 0xFF12, 0x0715, 0x1A16 }; word Y540[] = { 0x09E7, 0x3006, 0xF007, 0x0008, 0x6009, 0x2010, 0xA911, 0x1B12, 0x1F15, 0x2F16 }; word Y564[] = { 0x09E7, 0x6206, 0xF007, 0x0008, 0x6009, 0x3E10, 0x8911, 0x3312, 0x3C15, 0x5C16 }; word Y600[] = { 0x09E7, 0xBE06, 0xF007, 0x0008, 0x6009, 0x7C10, 0x8C11, 0x5712, 0x5815, 0x7016 }; Modifier les registres CRTC: (inspir‚ de l'init. des Modes X... voir plus ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ haut pour de plus amples d‚tails) mov esi,XVESA_Ptr cld lodsb or al,al ; Devons nous modifier le mode vid‚o de base ? jz NonMerci ; Non?Ä¿ La r‚ponse peut ˆtre "Non" car les initialisations mov dx,3C2h ; ³ de certains modes VESA mettent directement la out dx,al ; ³ bonne valeur pour le registre MISCELLANEOUS. NonMerci: ; <ÄÄÄÄÙ mov dx,3D4h mov al,11h out dx,al inc dx in al,dx and al,7Fh out dx,al dec dx lodsb xor ecx,ecx mov cl,al rep outsw Si vous ˆtes suffisament astucieux, vous pourrez combiner les constantes utilis‚es dans les Modes X pour obtenir plus de modes "VESA-X" tels que le 640x200, 800x480, etc... (mais je ne pense pas que ‡a marche convenablement avec les largeurs de 1024 pixels puisque ce mode est g‚n‚ralement entrelac‚... Mais qui sait?...) Je pense que le plus difficile est de trouver la bonne valeur du registre MISCELLANEOUS.