Práctica 1. Manejo de recursos y elementos básicos

(Este enunciado será explicado en la primera clase que corresponda a cada grupo)


Funcionamiento

La prueba consiste en la realización de una serie de procedimientos en ENSAMBLADOR que van a ser llamados desde unos programas en C que se proporcionan. Para que los diferentes ejercicios se puedan realizar de forma independiente (sin necesidad de haber hecho otro), se proporciona una librería donde ya están hechos. Según se realicen los distintos procedimientos por parte del alumno deben ser sustituidos los que se proporcionan en la librería por los realizados por el alumno.

Los ejercicios consisten en la creación de una serie de procedimientos que una vez realizados deberán sustituir a los existentes en la librería pra1.lib compilada en modelo LARGE. Se proporciona también un fuente en C, pra1.c . Este código realiza las pruebas de los procedimientos comprobando la devolución de errores, creando un fichero denominado log.txt con los errores no detectados o mal calculados. Si este fichero está vacío es que se controlan todos los errores. En una primera aproximación, y por simplificar, se puede utilizar el código p1_err.c, que realiza una prueba de todos los procedimientos pedidos pero no tiene en cuenta la gestión de errores. La entraga de la práctica con este código fuente puntuará menos que con el pra1.c.

Se recomienda no usar el entorno del TurboC sino compilar los fuentes en C y enlazar con el comando tcc. Las compilaciones en ensamblador se realizarán con el comando tasm y para meter y sacar módulos de la librería el comando tlib. Cualquiera de estos comandos, ejecutados sin parámetros, indican cómo deben ser usados. Las depuraciones podrán realizarse con el TurboDebugger (td) si se utilizan las banderas de compilación adecuadas. Es importante recordar el uso de las banderas -ml en C y /mx en ensamblador así como la declaración PUBLIC de los procedimientos en ensamblador.

Para facilitar el desarrollo se incluye un ejemplo de un procedimiento escrito en ensamblador, paleta.asm.

La definición detallada de todos los procedimientos que hay que diseñar, de sus parámetros y sus valores de retorno se encuentra en pra1.h.  Se incluye un fichero ejecutable que muestra el uso de todos los procedimientos y el resultado que se debe obtener tras cambiar todos los objetos de la librería entregada por los de los alumnos. pra1.exe  

Los ficheros prac1.c y pra1.h NO SE DEBEN MODIFICAR.

Un ejemplo de la secuencia de comandos a ejecutar para añadir el código de paleta.asm (suponer pareja 7 del turno 3a *) sería:

tasm /mx 3a07p1pp.asm             Se ensambla el fuente y se crea el objeto, 3a07p1.obj, siempre que no haya errores.

tlib pra1.lib -paleta +3a07p1pp     Se extrae el objeto original PALETA y se incluye el nuevo

tcc -ml pra1.c pra1.lib                  Se crea el ejecutable pra1.exe. Se ejecuta y si no funciona se pasa a la depuración. Para ello es necesario hacer el proceso anterior con las banderas correspondientes

En el anexo se muestra información sobre cómo acceder a la descripción de los caracteres y sobre el modo de pantalla MCGA.

Un resumen de los procedimientos que se tienen que diseñar en ensamblador es:

Nombre del Procedimiento Fichero Fuente * Nombre del objeto  en la librería ** Comentarios
void modo_mcga() xxxxxxmc.asm M_MCGA Para poner el modo se utilizará la interrupción 10h con AH=0 y AL=13h para el modo MCGA y AL=3h para el modo normal o texto
void modo_normal() xxxxxxmn.asm M_NORMAL
int Pixel (int x, int y, int color) xxxxxxpi.asm PIXEL

Debe ponerse el pixel accediendo directamente a la memoria y sin usar interrupciones

int Recta (int xi, int yi, int xf, int yf, int indice_color) xxxxxxre.asm RECTA  Algoritmo para pintar la recta: Recta.pdf

void Poner_Paleta_Colores (P_TABLA_COLORES tabla)

xxxxxxpp.asm PALETA  
int Caracter (int Caracter, int x, int y, int color) xxxxxxca.asm CARACTER Para poner los distintos pixels del carácter es necesario llamar al procedimiento Pixel. Se aconseja utilizar las instrucciones lógicas de rotación o desplazamiento de bits

int Texto (P_MIBYTE texto, int x, int y, int indice_color)

xxxxxxte.asm TEXTO  
int ComparaMemoria (P_MIBYTE memoria_uno, P_MIBYTE memoria_dos, int longitud) xxxxxxcm.asm COMPMEM

Deben utilizarse, obligatoriamente las instrucciones de cadena en ensamblador.  Los procedimientos devolverán los valores IGUAL o DISTINTO definidos en pract1.h

int ComparaTexto(P_MIBYTE texto_uno, P_MIBYTE texto_dos) xxxxxxct.asm COMPCAD

P_MIBYTE CopiaMemoria(P_MIBYTE memoria_fuente, P_MIBYTE memoria_destino, int longitud)

xxxxxxc2.asm COPIAMEM  

P_MIBYTE CopiaTexto(P_MIBYTE texto_fuente, P_MIBYTE texto_destino)

xxxxxxc3.asm COPIATXT  
int LongitudTexto(P_MIBYTE texto) xxxxxxlt.asm LONGTXT  

* Sustituir las xxxxxx por el nombre correspondiente a cada pareja según está descrito en las normas, es decir, grupo_pareja_práctica_orden.asm. Por ejemplo, 3a07p1pi.asm sería el nombre para el procedimiento Pixel de la práctica 1 de la pareja 7 del turno 3a (jueves mañana)

** Para obtener el nombre de los objetos basta con ejecutar tlib pra1.lib, pra1.lst. Con esto se crea un fichero de texto, pra1.lst donde figura el nombre del objeto y el de los procedimientos declarados como públicos

Se puede hacer una primera versión de los procedimientos que no incluyan el control de errores y añadírselo una vez que funcione, aunque en general ese control permitirá poder depurar de una manera más sencilla.


Anexos

Modo de vídeo MCGA

Para inicializar el modo de vídeo MCGA (320x200x256) se utiliza una llamada a la interrupción 10h. Ahora hemos de comprender como gestiona el ordenador esos pixels que escribimos en pantalla.

La dirección A000:0000 es el principio del segmento de VideoRAM, es decir, es donde la MCGA guarda los datos de las imágenes gráficas que dibuja en el monitor. Si escribimos algún valor en este segmento, la próxima vez que la tarjeta gráfica redibuje la pantalla (lo hace entre 50 y 70 veces por segundo) el valor que hemos escrito aparecerá en pantalla en forma de punto.

Para pintar un pixel basta con escribir en la posición de memoria correspondiente, el índice de color que queremos para que la tarjeta gráfica lo represente durante el próximo retrazado. El modo MCGA es el modo gráfico más sencillo en este sentido pues es un modo de 8 bits por pixel.

Esto quiere decir que cada número del 0 al 255 se corresponde con un color. Por defecto, el 0 es el negro, el 1 el azul, y así hasta llegar al 255. Entre el 0 y el 255 disponemos de gamas de azules, verdes, amarillos, etc..., que componen la paleta por defecto de la MCGA.

Que este modo gráfico sea de un byte por pixel significa que al escribir un byte en este segmento de memoria, su equivalente en pantalla será un pixel, que aparecerá automáticamente en cuanto el haz de electrones pase por esa posición al refrescar la imagen. En la figura adjunta tenemos una representación de cómo está organizada la VideoRAM en el modo 13h (MCGA).

Como puede verse, al byte 0 le corresponde el pixel (0,0) (el primero de la pantalla); al byte 1 le corresponde el pixel (1,0), al byte número 320 le correspondería el pixel (0,1), (primer pixel de la línea 1, porque hay 320 pixels de resolución horizontal) y así hasta el byte 63.999 del segmento, que corresponde a la posición (319,199). Depende del offset en que coloquemos el byte, el punto aparecerá en distinta posición en el monitor (cada byte es un pixel individual en la pantalla).

El segmento de la VideoRAM se comporta en este modo de video como si fuera una larga línea de pixels de manera que al llegar al final de una línea horizontal de pantalla, el siguiente byte de la VideoMemoria es el que continúa en la siguiente línea de pantalla. De ahí el término direccionamiento lineal: es como si la pantalla fuera un array unidimensional desde 0 a 64.000 donde cada 320 bytes estamos situados en una nueva línea de pantalla (el byte 320 es el primer pixel de la segunda línea). Así, durante el retrazado la tarjeta únicamente tiene que dedicarse a leer bytes (todos ellos consecutivos) y representarlos en pantalla.

Algunos links sobre el modo MCGA

      Curso de programación gráfica

      Modos gráficos. El Universo Digital

 

Caracteres de gran tamaño

La idea se basa en explorar la tabla de caracteres empleada internamente por el ordenador. Esta tabla se encuentra en la memoria ROM, a partir de la dirección F000:FA6E. La forma de cada carácter está descrita por 8 bytes, cada uno de los cuales representa una fila, según se muestra a continuación:

Carácter

............

Representación en ROM

   0011 1110 = 3EH
   0110 0011 = 63H
   0110 1111 = 6FH
   0111 1011 = 7BH
   0111 0011 = 73H
   0110 0011 = 63H
   0011 1110 = 3EH
   0000 0000 = 00H

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 .

 

 

 

 

 

 

 

 

 La figura representa el número '0', el conjunto de 8 bytes forma una retícula de 64 bits. Los bits que están a '1' definen el contorno del carácter, es decir, los puntos que habrá que iluminar en una pantalla para conseguir una representación del carácter.

La tabla de todos los caracteres del 0 al 127 está ordenada según el código ASCII. Por tanto, para acceder a un carácter concreto habrá que sumar a la posición inicial (F0000:FA6EH) un desplazamiento que será igual al número ASCII del carácter multiplicado por 8, puesto que, como ya sabemos, cada carácter está representado mediante 8 bytes consecutivos.

Una vez que se conoce la dirección donde está almacenada la representación del carácter que se quiere imprimir, se toman los datos byte a byte (fila a fila) y se va examinando cada uno de los bits individuales. Si el bit correspondiente es '0', el procedimiento escribirá un espacio en la pantalla, mientras que si el bit examinado es un '1', se escribirá un carácter grueso ( ). Al terminar de escribir una fila habrá que colocar el cursor en la posición correspondiente a la primera columna de la siguiente fila, y volver a repetir la operación hasta terminar de explorar las 8 filas.


Plazo de entrega : La presentación y evaluación de esta práctica será la indicada en el calendario, según el grupo (ver calendario ). 



Ejercicios previos.

Estos ejercicios se proponen como un "entrenamiento" a la programación en ensamblador. La realización de estas rutinas será provechosa para la primer
a práctica, pues permitirá conocer  de forma sencilla como manejar ciertos dispositivos de manera independiente..


Página editada y mantenida por Guillermo Glez. de Rivera
  Volver
al proyecto