From: baldo AT chasque DOT apc DOT org Message-Id: <3.0.1.32.19970602034943.0068b004@chasque.apc.org> Date: Mon, 02 Jun 1997 03:49:43 -0300 To: "Grzegorz Hankiewicz" Subject: RE: How to access the vide memory under DJGPP to print text. Cc: djgpp AT delorie DOT com In-Reply-To: <199707082045.TAA23224@mail.jet.es> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Precedence: bulk At 09:23 PM 08/07/1997 +0200, you wrote: >¿mailing list de DJGPP? No sabía que había de eso. ¿Podrías decirme como >suscribirme a ella? Mandá una carta sin tema (subject) y escribí add djgpp. Esta carta la mandas a listserv AT delorie DOT com. Despues que te subscribas te van a llegar varias cartas que son las cartas que mandan a djgpp AT delorie DOT com y las que mandan a djgpp-announce AT delorie DOT com. Yo de ahí ayudo a algunas personas (como a vos) y tambien aprendo de las ayudas que hacen otros a otras personas. >> Bueno, el buffer de texto está compuesto por columnas y filas al igual >que >>el buffer grafico de VGA, pero cada celda está compuesta por 16 bits que >>contienen el caracter y los colores del mismo. La estructura de cada >celda >>es la siguiente: >> 8 bits - Código ASCII del caracter. >> 3 bits - Color del texto. >> 1 bit - Si está encendido significa color de alta intensidad, si está >>apagado significa color de baja intensidad. >> 3 bits - Color del fondo. >> 1 bit - Si está activado hace que el caracter titilee (blink), si está >>apagado el caracter aparece siempre. >El problema es ahora acceder a los bits individualmente. ¿Cómo lo haces? Es muy fácil si creas una estructura de bits. Supongo que para DJGPP sería así: struct CELDA_CARACTER { unsigned :8 ASCII __attribute ((packed)); unsigned :3 CTEXTO __attribute ((packed)); unsigned :1 INTENSIDAD __attribute ((packed)); unsigned :3 CFONDO __attribute ((packed)); unsigned :1 TITILA __attribute ((packed)); } CELDA; Bueno, no quiero entran en detalles de las estructuras, supongo que sabrás algo de C. Podes por ejemplo acceder a CTEXTO de la siguiente manera: CELDA.CTEXTO=7; >> Si estas en 80x25 o 80x50 es lo mismo, no hay que cambiar de banco o de >>pagina ni nada de eso, es muy simple. Podés usar una matriz en memoria >ram >>y despues volcarla al buffer de texto que está localizado a 0xb800. No >hice >>ninguna rutina de esto para DJGPP, pero si queres te puedo dar unas que >>tengo que están hechas para Microsoft C/C++ 7.0. >Me encantaría verlas :-) OK, están muy desprolijas, pero te las mando porque capas que te sirven. Te aviso que no te van a andar con el DJGPP. >> Para poner el modo de texto es muy simple, cargas AX con 0x3 y llamar a >la >>interrupcion 0x10. Esto te pone el modo de texto 80x25. Si queres poner >>80x50 tenes que primero poner el modo de texto 80x25 como te dije y >despues >>cargar AX con 0x1112 y llamar a la interrupcion 0x10. >Vaya. Eso de los registros me suena a ensamblador, y yo de eso no tengo ni >idea. En una revista ví un código que activa el modo 320x200 y lo retoqué >quedándome así : >#include >#include >void main(void) >{ > union REGS ent,sal; > > ent.h.al= 0x3; > ent.h.ah= 0; En vez de eso probá: ent.x.ax=0x3; > int86(16, &ent, &sal); // Ahí pongo el modo 80x25 como dices > ent.h.al=0x12; > ent.h.ah=0x11; En vez de eso probá: ent.x.ax=0x1112; > int86(16, &ent, &sal); // Y aquí el 80x50. >} >Yo mismo me quedé alucinado. Funciona. Y conociendome a mi mismo, es una >grata sorpresa. >El problema va a ser ahora hacer lo de la copia a memoria y lo de la >paleta. Para cambiar la paleta usaba el Allegro, pero claro, ahora me tengo >que buscar la vida. ¿Sabes cómo cambiar la paleta? Aunque sea en modo >320x200 ... No, nunca probé hacerlo y tampoco se como hacerlo, lo siento. :-( >Y en lo que dices de crear un array y volcarlo a la 0xb800 , ¿cómo se >hace? union { CELDA_CARACTER; /*esto corresponde a la estructura que te mostré al inicio pero sin inicializarla.*/ unsigned int VALOR; } CELDA; unsigned int RAM[80*50]; //para una pantalla de 80x50 Vos accedes al codigo ASCII y a los atributos de la siguiente manera: CELDA.ASCII='a'; CELDA.CTEXTO=7; Despues que llenas la estructura, pones el resultado en el buffer de la RAM: RAM[X+Y*ANCHO]=CELDA.VALOR; Donde X e Y son las coordenadas y ANCHO es el ancho de la pantalla que estés usando (ej:80). No tenes porqué cambiar siempre los atributos de la estructura CELDA, estos quedan con el ultimo valor asignado. Luego para volcar la pantalla te haces una rutina con algo de esto: if(!__djgpp_nearptr_enable()) return 0; //esto es por si falla. unsigned int *PANTALLA=(unsigned int *)(__djgpp_conventional_base+0xb8000); unsigned POSICION; for(POSICION=0; POSICION=80*50; POSICION++) { PANTALLA[POSICION]=RAM[POSICION]; } Disculpa que sea tan conciso, pero no tengo mucho tiempo. Espero que hallas entendido y puedas implementarlo. Por cualquier duda no dudes en preguntarme. >Y rizando el rizo... ¿sabes como poner los modos esos raros de >132xalgo(creo que 50) ? No, eso no se. Te aviso que te mandé en otra carta 2 archivos: TXTDI.H y PEEKPOKE.H. Cuidado que no testié ninguna de las cosas que te escribí, espero que esten bien. Si no es así intenta cambiarlas para que funcionen, y si no te funcionan decime porqué no funcionan, que te dice el compilador y todo lo que creas necesario decirme. Voy a mandar esta carta también al mailing list, talvez alguien tambien esté tratando hacer lo mismo o talvez me corrija y pueda ayudarte tambien. Bueno, saludos y suerte con las rutinas! Ivan Baldo: baldo AT chasque DOT apc DOT org - http://www.chasque.apc.org/baldo