EL SUBSISTEMA DE VIDEO

El subsistema de vídeo (VIO) es el encargado de gestionar la comunicación entre los programas y la pantalla. Es, sin duda, el subsistema más complejo de los tres, y el que ofrece, por tanto, mayores posibilidades.

Dado que puede haber varios programas ejecutandose a la vez en el sistema, pero solo uno puede acceder a la vez a la pantalla (normalmente el programa que se encuentra en primer plano o foreground), es necesario virtualizar ésta por medio de un buffer de pantalla propio de cada programa: el LVB (Logic Video Buffer, buffer de vídeo virtual). Cuando una aplicación quiere escribir en pantalla y se encuentra en segundo plano (background), su salida se escribe en dicho LVB. En el momento en que el usuario conmuta dicho programa a primer plano, el LVB se copia tal cual en la memoria de pantalla, y el resto de las escrituras van a ésta directamente. Si se vuelve a conmutar dicho programa a segundo plano, OS/2 copia lo que hubiese en pantalla en ese momento al LVB. De este modo, el programa nunca sabe ni le preocupa cuando está en primer o en segundo plano.

FUNCIONES VIO

Salida por TTY virtual

En un extremo se encuentra el primer servicio que ofrece el subsistema VIO, que es el de salida TTY. Este servicio es casi idéntico a la salida de caracteres por medio del sistema de archivos. De hecho, éste, cuando comprueba que lo que el programa envía va dirigido a la pantalla, usa este servicio para realizar la función.

¿Cual es la diferencia entre uno y otro, entonces? Las diferencias son dos: la primera es que el uso del subsistema VIO es una opción más rápida que el sistema de ficheros; la segunda es que si usamos el subsistema, no podremos redireccionar la salida a un fichero, o a otro dispositivo de salida. Siempre irá a la pantalla.

El servicio TTY admite los caracteres de control estandar del ASCII, y también puede soportar ANSI, si éste es activado mediante la llamada correspondiente.

VioWrtTTY
VioGetAnsi
VioSetAnsi
VioGetMode
VioSetMode
VioGetState
VioSetState

Salida de cadenas de caracteres

Los siguientes servicios se encargan del tratamiento de la pantalla a más bajo nivel. Con ellos podemos imprimir largas cadenas de caracteres con atributos y leer los caracteres que hay en determinadas posiciones de la pantalla. También podemos repetir un caracter o una pareja caracter-atributo un número determinado de veces.

Los atributos son bytes que definen el color de tinta y de fondo para cada caracter, así como otras características como el parpadeo. Están compuestos por un byte, el cual se divide en dos nibbles (grupos de 4 bits). El nibble de menor peso determina el color de la tinta del caracter, y el de mayor peso el color de fondo y, según se encuentre activo o no, el parpadeo del caracter. La distribución es como sigue:

Parpadeo activado
Bit Significado
7 Parpadeo del caracter
6 Rojo del fondo
5 Verde del fondo
4 Azul del fondo
3 Intensidad de la tinta
2 Rojo de la tinta
1 Verde de la tinta
0 Azul de la tinta
Intensidad activada
Bit Significado
7 Intensidad del fondo
6 Rojo del fondo
5 Verde del fondo
4 Azul del fondo
3 Intensidad de la tinta
2 Rojo de la tinta
1 Verde de la tinta
0 Azul de la tinta

Los bits de color activan directamente cada una de las componentes del monitor, de modo que éstas se suman directamente, dando lugar a los siguientes colores:

0 Negro 1 Azul 2 Verde 3 Celeste
4 Rojo 5 Magenta 6 Amarillo 7 Blanco

El bit de intensidad se limita a hacer estos colores más o menos brillantes.

Estos servicios orientados a caracter siguen siendo independientes del hardware utilizado de modo que no es necesario saber como se trabaja a nivel físico con ellos. Por otra parte, el propio OS/2 optimiza las transferencias para cada uno de ellos, de modo que se consigue la mayor velocidad posible, y se eliminan ciertos problemas inherentes a algunos sistemas gráficos (por ejemplo, en las tarjetas CGA sincroniza automáticamente la escritura con el retrazado vertical, de modo que se evita la aparición de nieve en la pantalla).

Tanto cuando hacemos una lectura como una escritura, si excedemos el fin de una línea se seguirá leyendo en la siguiente, y si llegamos al final de la pantalla no se seguirá leyendo ni imprimiendo.

VioWrtCellStr
VioWrtCharStr
VioWrtCharStrAtt
VioWrtNAttr
VioWrtNCell
VioWrtNChar
VioReadCellStr
VioReadCharStr

Funciones de Scroll

El subsistema VIO ofrece, además, la posibilidad de realizar scroll de ventanas en modo texto. Con este conjunto de funciones, podemos desplazar parte o toda la pantalla en cualquiera de las cuatro direcciones posibles. La razón de incluirlas es que resulta mucho más rápido que hacer una rutina que lea cada posición del buffer de video y la reescriba en el lugar adecuado, aparte de que se trata de una función muy común en casi cualquier programa.

VioScrollDn
VioScrollLf
VioScrollRt
VioScrollUp

Definición y movimiento del cursor

El cursor (el cuadradito parpadeante) es totalmente definible por el usuario en las sesiones de texto y gráficos de OS/2. Podemos definir tanto su tamaño como su posición dentro del caracter.

Al contrario que en MS-DOS, cuando escribimos en la pantalla de OS/2 la posición del cursor no se cambia. Esto se hace así para ganar tiempo. Normalmente el cursor solo se usa cuando hay que introducir datos por teclado, y el resto de las veces se suele hacer desaparecer de la pantalla. Esta es la razón de que halla un conjunto de funciones para situar el cursor. De esta manera se gana en velocidad.

VioGetCurPos
VioSetCurPos
VioGetCurType
VioSetCurType

Acceso al LVB

Cuando se necesite alta velocidad, se puede pedir acceso directo al buffer virtual de video asociado con la aplicación. Al hacerlo, OS/2 devuelve un puntero a la zona de memoria en donde está situado, con lo que podremos escribir en él como si se tratase de la pantalla física. Una vez que hemos terminado, debemos enviar una orden de retrazado, que hará que OS/2 copie el LVB a la pantalla física (siempre que la aplicación se encuentre en primer plano). Esto significa que los cambios que hagamos en el LVB no son visibles hasta que nosotros queramos.

Usar esta opción implica que perdemos el aislamiento entre el hardware y nosotros: dado que el LVB no es más que una copia del buffer real de pantalla, es necesario que nuestro programa conozca la geometría y la forma de almacenamiento de los datos en ésta.

VioGetBuf
VioShowBuf

Acceso directo al buffer real de video

En el extremo opuesto se encuentran las funciones de acceso directo al video. Con ellas, OS/2 da acceso directo a la memoria de pantalla. Sin embargo, esto que en el DOS de siempre es la opción más normal y común, puede resultar catastrófico en un Sistema Operativo multitarea como OS/2; no se hundiría el suelo bajo nuestros pies, pero la pantalla podría ser alterada en un momento poco oportuno... si OS/2 no tomase las debidas precauciones.

Para que un programa pueda acceder directamente a la memoria real de video, es absolutamente necesario que se encuentre en primer plano. Esto es así porque si escribiese algo en pantalla cuando estuviese en background, machacaría la imagen de la aplicación que se encontrase en ese momento en primer plano.

Lo primero que hay que hacer es pedir la dirección física de la memoria de vídeo. OS/2 devuelve un selector (o varios) a dicha zona de memoria (ver modos de direccionamiento del 286). Estos selectores deben ser convertidos a punteros antes de poder trabajar con ellos. Pueden ser varios pues cada selector no puede apuntar a un bloque de memoria mayor de 64Ks, el cual es también, casualmente, el tamaño de cada bloque de memoria de las tarjetas de vídeo actuales. Esto ayuda a simplificar el acceso, pues en modos como 640x480x16colores no necesitaremos cambiar de bancos; OS/2 nos devuelve un selector que apunta a cada uno de ellos, con lo que solo tenemos que acceder normalmente como si fuese memoria lineal, y el Sistema Operativo conmutará de uno a otro automáticamente.

El hecho de obtener un selector no significa que dispongamos de acceso todavía a la pantalla. De hecho, si intentásemos escribir o leer algo en ese momento y la aplicación no se encontrase en primer plano, OS/2 la cerraría inmediatamente, dando un Fallo de Protección General (el cual ya sabemos que no es tan fatal como el de Windows, pues en OS/2 solo afecta a la aplicación que lo ha provocado, dejando intacto al Sistema Operativo y al resto de los programas).

Cada vez que queramos acceder a la memoria física de video, debemos bloquear el acceso al buffer. Si el programa estaba en primer plano, OS/2 devolverá un valor afirmativo al retornar de la llamada, y bloqueará el selector de programas. Esto significa que el usuario no podrá conmutar la sesión actual a segundo plano hasta que ésta termine el acceso. Sin embargo, el resto de las aplicaciones siguen funcionando en segundo plano, sin verse afectadas por este hecho. Por supuesto, esto puede ser peligroso, y OS/2 toma algunas precauciones: si el sistema está bloqueado y el usuario hace una conmutación de tarea, si el programa no desbloquea el conmutador antes de un cierto tiempo definido por el sistema, queda congelado y se realiza la conmutación. Por eso es recomendable desbloquear cada x tiempo el selector de programas y volverlo a bloquear.

Si por el contrario el programa se encontraba en segundo plano, hay dos opciones: OS/2 puede retornar un código de error al programa, con lo que este sabrá que no tiene acceso al buffer y puede seguir trabajando en otra cosa, o bien OS/2 congelará al programa hasta que el usuario lo pase a primer plano, momento en que lo despertará indicandole que tiene acceso al buffer real.

Una vez que OS/2 ha devuelto un resultado afirmativo, el programa tiene acceso total a la memoria de video. Cuando haya terminado, tiene que proceder a desbloquear la pantalla, de modo que OS/2 pueda desbloquear el selector de programas y devolver el sistema a la normalidad.

VioGetPhysBuf
VioScrLock
VioScrUnLock

Existe una dificultad adicional a la hora de trabajar con acceso directo a la pantalla. Se trata de que OS/2, al conmutar de una tarea a otra, solo guarda el contenido de la pantalla si ésta se encontraba en modo texto (esto se cumple para OS/2 1.x. En Warp 4, sin embargo, SI conserva el contenido de la pantalla, pero no se si se cumple también para OS/2 2.x o 3.x). Si estabamos trabajando en modo gráfico, el contenido se perderá. Para evitarlo, OS/2 facilita la posibilidad de crear un thread (este concepto será explicado más adelante, cuando veamos la multitarea a fondo) que será activado cuando el programa vaya a cambiar de primer a segundo plano, y viceversa. Esto es así para permitir que un programa pueda almacenar el contenido de la pantalla en modo gráfico cuando no tiene bloqueado el acceso a la memoria de video. Es el thread SavRedrawWait.

Para implementarlo, es necesario crear un nuevo thread en el que se ejecute la llamada VioSavRedrawWait. Esta llamada bloqueará el thread hasta que el usuario pulse CTRL+ESC, momento en que OS/2, antes de conmutar de tarea, despertará a dicho thread indicándole que debe almacenar el contenido de la pantalla. Cuando el thread termine, debe volver a ejecutar la llamada, con lo que OS/2 sabrá que ha finalizado. El thread se quedará dormido de nuevo, y solo será despertado cuando el usuario vuelva a conmutar a primer plano el programa. Entonces OS/2 le indicará que debe repintar la pantalla.

VioSavRedrawWait

La inclusión de este sistema de acceso puede parecer innecesaria, a la vista de la potencia del acceso al LVB; la razón de haberla implementado fue que, cuando salió OS/2, no llevaba todavía el Presentation Manager, el gestor de ventanas, sino que era un Sistema Operativo en modo texto, por lo que se incluyó este sistema para poder acceder en modo gráfico a la pantalla, dado que VIO no ofrece ninguna facilidad como el trazado de puntos o líneas. Actualmente, al disponer de un completo (y complejo) gestor de ventanas, este método puede parecer inutil, sin embargo, para juegos puede ser muy útil, pues permite acceder a pantalla completa en modos como 320x200 en 256 colores, lo que permite una alta velocidad de refresco, así como una gran facilidad de manejo. Hay que señalar que el acceso directo a la memoria de vídeo solo se puede hacer estando en una sesión de pantalla completa; no funcionará en una sesión de ventana.

Pagina anterior  Indice  Pagina siguiente