/*--------------------------------------------------------------------------
   VGA_T2-1.c - Jugando con las dimensiones de la pantalla
  --------------------------------------------------------------------------
   El programa pretende ser efectivo, esto es:lograr sus objetivos, aunque
   puede que no sea eficaz (No he optimizado nada)
  --------------------------------------------------------------------------*/
#include <conio.h>

void Set320x200NE( void );
void SetPixelNE(int x, int y, int color, int Alogico);
void SetTextMode80C( void );
void SetStartAdress( int despl );
void OutReg(int reg, int indice, int valor);
int  InReg(int reg, int indice);
void DrawBox(int x, int y, int ancho, int alto, int color);

unsigned Alogico=90;  /* Ancho logico de 90*4=360 pixels laterales */


/*+COMIENZO DE MAIN+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  Funcion principal.
  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
main()
{
 unsigned x,y,Atotal,Adisp,Blanq,Retraz, re;

/*--------- Presentamos un poco de que va el programa */
	SetTextMode80C();
	puts("Vas a ver a continuacion un cambio dinamico de las");
	puts("dimensiones fisicas de la pantalla.");
	puts("Veras como pasa de una resolucion de 320 puntos horizontales");
	puts("a un maximo de 360 y a un minimo de 280");
	puts("Para que lo veas bien, apareceran en la pantalla grupos de");
	puts("rectangulos de 20x45. La pantalla original sera de 320x200.");
	puts("Cuando pulses una tecla, las dimensiones cambiaran.");
	puts("\nAunque en mi monitor la pantalla se centra automaticamente,");
	puts("se que no lo hace en todos. Esto se debe a que solo he");
	puts("cambiado algunos de los registros. Para mas detalles, examina");
	puts("el fichero fuente.");
	puts("\nPulsa una tecla");
	getch();

/*--------- Establecemos el modo no encadenado */
	Set320x200NE();

/*--------- Damos un ancho logico a la pantalla de 90*4=360 puntos */
	OutReg(0x3d4,0x13, Alogico);

/*--------------------------------------------------------------------------
   Permitimos el acceso a los indices 0-7 del CRTC
  --------------------------------------------------------------------------*/
	re=InReg(0x3d4,0x11);
	re=re&127;
	OutReg(0x3d4,0x11,re);

/*--------------------------------------------------------------------------
   Llenamos la pantalla virtual de rectangulos de colores de 20x45.
   Fijate que 320/20=16 que son el nro. de cuadrados horizontales que
   veras al empezar el programa. Cuando aumentemos la resolucion fisica,
   podras ver alguno mas.
   Esperamos una tecla.
  --------------------------------------------------------------------------*/
	for(x=0;x<18;++x){
	for(y=0;y<9;++y){
	   DrawBox(x*20,y*45,20,45,y*16+x);}}
	getch();

/*--------------------------------------------------------------------------
   Leemos:
     - El ancho total
     - El nro. de pixels visualizados
     - El registro de comienzo de blanqueo
     - El registro de comienzo de retrazado
  --------------------------------------------------------------------------*/
	Atotal=InReg(0x3d4,0x00);
	Adisp =InReg(0x3d4,0x01);
	Blanq =InReg(0x3d4,0x02);
	Retraz=InReg(0x3d4,0x04);


/*--------------------------------------------------------------------------
   Recuerda que la pantalla en modo 13h tiene una resolucion de 320x200.
   Hacemos tres bucles. En el primero aumentamos la resolucion hasta un
   maximo de (80+10)*4=360 puntos visibles, por lo que podremos ver un total
   de 360/20=18 cuadrados laterales. El segundo bloque reduce progresivamente
   la pantalla hasta dejarla a (80-10)*4=280 puntos. El tercero restablece
   sus dimensiones originales.
  --------------------------------------------------------------------------*/
	for(x=0;x<10;++x){
		OutReg(0x3d4,0x01,Adisp++);
		OutReg(0x3d4,0x02,Blanq++);
		OutReg(0x3d4,0x04,Retraz++);
		for(y=0;y<50000;++y);}
	for(x=0;x<20;++x){
		OutReg(0x3d4,0x01,Adisp--);
		OutReg(0x3d4,0x02,Blanq--);
		OutReg(0x3d4,0x04,Retraz--);
		for(y=0;y<50000;++y);}
	for(x=0;x<10;++x){
		OutReg(0x3d4,0x01,Adisp++);
		OutReg(0x3d4,0x02,Blanq++);
		OutReg(0x3d4,0x04,Retraz++);
		for(y=0;y<50000;++y);}

/*--------------------------------------------------------------------------
   Deshabilitamos el acceso a los indices 0-7 del CRTC
  --------------------------------------------------------------------------*/
	re=InReg(0x3d4,0x11);
	re=re|128;
	OutReg(0x3d4,0x11,re);


/*--------------------------------------------------------------------------
   Esperamos tecla. Restablecemos el modo de texto
  --------------------------------------------------------------------------*/
	getch(); SetTextMode80C();
}
/*+FIN DE MAIN++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/







/*--------------------------------------------------------------------------
   DrawBox - Dibuja un cuadrado en la pantalla virtual del color escogido
  --------------------------------------------------------------------------*/
void DrawBox(int x, int y, int ancho, int alto, int color)
{
 unsigned cx,cy;
 for(cx=0;cx<ancho;++cx){
 for(cy=0;cy<alto;++cy){ SetPixelNE(x+cx,y+cy,color,Alogico); }}
}

