Hace poco me vino a la cabeza un recuerdo de cuando era un pequeño trasto con mi PS/1, donde a veces pasaba el rato haciendo trastadas con el QuickBASIC 4.5 a base de modificar código ya existente.
Con eso empecé a aprender a programar de forma un poco autodidacta. Empecé a hacer mis programillas a base de GOTOs, de IFs, de FOR..NEXTs… y luego empecé a tocar instrucciones más dedicadas a gráficos como LINE, DRAW, PUT, CIRCLE, etc, usando otros modos de pantalla gracias a la instrucción SCREEN.
La cosa se empezó a liar bastante cuando ya empecé a tocar cosas con POKE, PEEK o OUT llegando hasta a romper DOS, pero eso lo dejaré para otro capítulo de mis historias.
De momento hablaré de cómo un día, sin querer, la interfaz de QB45 en mi ordenador pasó a tener este aspecto:
El descubrimiento
La cosa empezó cuando estuve “jugando” con uno de los programas que venían de ejemplo en QuickBASIC 4.5, en concreto uno llamado BALLPSET.BAS, conocido por mí como “el programa de la pelota que borra”.
Este programa era una demostración que venía incluída en los diskettes de QuickBASIC. En él, se dibujaba por pantalla una rejilla cuadriculada, parecida a una portería de fútbol, y una pelota blanca que rebotaba y trazaba una trayectoria parabólica por donde pasaba usando el parámetro PSET en la instrucción gráfica PUT.
Había otro programa que era BALLXOR.BAS que hacía lo mismo, pero sin borrar la “portería” de fondo y la bola invertía los colores del fondo.

Para poder trazar estos gráficos, el programa necesitaba ejecutarse en el modo 4h de la BIOS, definido por QuickBASIC mediante la orden SCREEN 2, el cual establecía una resolución de pantalla CGA de 640x200 píxeles a 2 colores (monócromo).
La cosa es que QuickBASIC tenía una opción para salir momentáneamente al intérprete DOS sin perder el trabajo actual de QB45. En realidad, esto lo que hacía era abrir otra instancia del COMMAND.COM dentro de QuickBASIC conservando la última resolución de pantalla utilizada en el programa, lo cual quiere decir que si estabas ejecutando dentro de QuickBASIC un programa que usase la resolución y colores definidos por SCREEN 2, te abría una consola de comandos usando dicha resolución.
Esta opción la utilizaba yo a veces para hacer pruebas en caliente con otros programas. Hasta que un día se me ocurrió iniciar otra instancia de QB45 dentro de otra instancia de DOS inicializada previamente desde QB45 con SCREEN 2, al ser la resolución de vídeo que usaba el mencionado ejemplo de la bolita blanca.
Abrí un nuevo programa en QuickBASIC y… ¡tachán! De repente veo que toda la interfaz cambia del color azul con menús grises que trae de serie el QuickBASIC, a un fondo azul con menús de un color naranja que nunca había visto en modo texto dentro de la consola:
Es más, en ese punto, cuando ejecutaba el programa BALLPSET o BALLXOR en estas condiciones, ocurría algo que me resultaba aún más curioso:

Lo interpretaba como que el programa intentaba trazar los gráficos en modo texto, generando esa basurilla animada de colores cuando en realidad se trataba, supuestamente, de la mismísima pelota rebotando por dentro del marco.
Luego fui probando otros programas y el QuickBASIC ya se estaba quejando por momentos de que no tenía memoria suficiente, a veces ni siquiera podía cambiar a otro directorio dentro del diálogo de Abrir programa. También en cierto momento llegué a ver que de repente “desaparecían” todas las letras de la consola, o incluso que a veces algunas letras se mostraban como “gurruños” por pantalla.
Asustado, lo primero que hice fue decirle a mi padre: «creo que se ha metido un virus en el ordenador», lo cual era prácticamente imposible, ya que este ordenador no estaba conectado a internet y por lo general nunca guardábamos nada descargado de internet en los disquetes en las pocas veces que nos conectábamos a internet (por módem de 56kbps) en esa época. Pero claro, imagínate cómo era yo con 8 años de edad…
Mi padre vio el QuickBASIC con los colores alterados y ese programa de BALLPSET con códigos ASCII por todos los lados, y se limitó a decir: «eso es que estás tocando algo con el POKE», lo cual tampoco era cierto.

Más tarde se me ocurrió meterme en Opciones para cambiar los colores de presentación del programa, y empecé a ver que el selector de colores del programa mostraba otros colores “raros” aparte de los que había ya visto. El color azul se mostraba de color blanco, el verde de color amarillo, el cían de color más apagado, el rojo de color celeste, o el magenta de color verde. Los consideraba “raros” porque no estaban dentro del espacio de colores estándar de VGA cuando trabaja en modo texto.
Desde pequeño supe que dentro de los 16 colores soportados por VGA en modo texto, los 8 últimos eran una copia más “brillante” de los 8 primeros colores. Es decir, si el color 0 era el negro, el color 8 era el negro claro (gris oscuro), mientras que si el color 1 era el azul, el 9 era el azul claro, etc. Con esta paleta de colores cambiada no se cumplía esa regla, y en su lugar se mostraban colores que nunca había llegado a ver en modo texto.
Dejo a continuación una tabla comparativa de cómo tienen que ser los colores VGA estándar con su índice de color, y cómo se veían tras haber aplicado sin querer este curioso “filtro”:
| Índice | Paleta VGA estándar | Paleta VGA "enrarecida" | ||
|---|---|---|---|---|
| 0 | Negro | Negro | ||
| 1 | Azul | Blanco | ||
| 2 | Verde | Amarillo | ||
| 3 | Cían | Amarillo oscuro | ||
| 4 | Rojo | Azul celeste | ||
| 5 | Magenta | Verde lima oscuro | ||
| 6 | Marrón | Verde lima | ||
| 7 | Gris | Rojo anaranjado | ||
| 8 | Gris oscuro | Cían claro | ||
| 9 | Azul claro | Amarillo | ||
| 10 | Verde claro | Amarillo oscuro | ||
| 11 | Cían claro | Fucsia | ||
| 12 | Rojo claro | Verde lima oscuro | ||
| 13 | Magenta claro | Verde lima | ||
| 14 | Amarillo | Rojo anaranjado | ||
| 15 | Blanco | Marrón | ||
Guardé en la configuración de colores de forma que el fondo de la pantalla en el IDE fuera de color 12 (verde lima oscuro) con texto de color 2 (amarillo). Cuando arranqué de nuevo QuickBASIC en condiciones normales, vi que la pantalla pasó a recuperar los colores estándares de VGA y por ende, a mostrarse con texto verde sobre fondo magenta. Una combinación que chirriaba mucho a la vista y que por tanto tuve que deshacer rápidamente.
Qué frustración tan gorda para mi “yo” de 8 años el no poder guardar permanentemente esa configuración de colores…
Entonces me puse a estudiar el comportamiento de QuickBASIC cuando realizaba esta enrevesada operación. El único patrón que era capaz de observar era que algunos colores se repetían, por ejemplo los colores 2 y 9, los colores 3 y 10 o los colores 5 y 12 entre otros. Pero aún no terminaba de entender por qué ocurría este fenómeno.
Lo siguiente que probé fue a repetir la misma operación, pero con la resolución CGA de 320x200 píxeles que ofrecía la instrucción SCREEN 1. Ejecuté un programa a dicha resolución, salí al DOS, volví a abrir otra instancia de QB45, y al abrir un programa, QuickBASIC pasó a tener esta paleta:
La nueva tabla de colores quedaba por tanto así:
| Índice | Paleta VGA estándar | Paleta VGA "enrarecida" | ||
|---|---|---|---|---|
| 0 | Negro | Negro | ||
| 1 | Azul | Cían claro | ||
| 2 | Verde | Magenta claro | ||
| 3 | Cían | Blanco | ||
| 4 | Rojo | Negro | ||
| 5 | Magenta | Blanco | ||
| 6 | Marrón | Amarillo | ||
| 7 | Gris | Amarillo oscuro | ||
| 8 | Gris oscuro | Azul celeste | ||
| 9 | Azul claro | Verde lima oscuro | ||
| 10 | Verde claro | Verde lima | ||
| 11 | Cían claro | Rojo anaranjado | ||
| 12 | Rojo claro | Cían claro | ||
| 13 | Magenta claro | Amarillo | ||
| 14 | Amarillo | Amarillo oscuro | ||
| 15 | Blanco | Fucsia | ||
Yo en ese momento estaba literalmente flipando en colores. Y a la vez estaba dándole vueltas a mi cabeza buscando una explicación de por qué ocurría eso y sobre todo si podía encontrar alguna forma de emular ese comportamiento sin tener que agotar toda la memoria del sistema.
En eso, me di cuenta de que los cuatro primeros colores (índices del 0 al 3) pertenecen al conjunto de la paleta de colores #1 de CGA, el cual se solía ver en muchos videojuegos que soportaban este modo gráfico. Esta pista ya me decía mucho sobre lo que podía estar pasando, y deduje que, de alguna manera, la instrucción SCREEN también alteraba la paleta de colores según el modo de pantalla escogido. Pero aún no podía entender por qué se asignaban otros colores “raros” en el resto de índices de colores, más aún cuando se supone que SCREEN 2 supuestamente sólo soporta gráficos monócromos.
Mi padre supuso que esto era obra de mis trastadas con POKE y PEEK, lo cual ya me dio una pista sobre por dónde podía atacar para poder conseguir mi objetivo de emular este comportamiento. El problema es que, por mucho que tirara de manuales antiguos de DOS o de QuickBASIC, no encontraba ningún tipo de documentación que me diera más pistas sobre cómo acceder a la memoria de vídeo jugando con las instrucciones POKE o OUT de QuickBASIC. Mi frustración fue aumentando a la vez que me fui olvidando poco a poco de seguir calentándome la cabeza con este asunto.
Continúa la investigación

Pasaron los años y descubrí DOSBox, lo cual me fue muy útil para poder arrancar ciertos programas de DOS puro que ya me resultaban imposibles de abrir en Windows XP, sistema que usaba por aquél entonces.
Una de las primeras cosas que probé fue reproducir de nuevo esa misma trastada con QuickBASIC, con la comodidad de no tener que preocuparme esta vez por la falta de memoria. Fui anotando los códigos hexadecimales de cada color con ayuda de Photoshop y busqué cada uno de los códigos de color por internet para poder retomar mi investigación personal y saber de dónde salían esos colores raros de la consola.
Finalmente acabé encontrando una tabla de los 64 colores que soportaba EGA, donde vi que se listaban prácticamente todos los colores raros que fui obteniendo con este “no sé si llamarlo bug” de QuickBASIC.
Indagando por los registros de CPU y de memoria virtuales con ayuda del depurador de DOSBox, descubrí además que cuando ejecutaba cualquier programa de QuickBASIC en SCREEN 1 o 2, se modificaba también la paleta de colores del adaptador gráfico a nivel de hardware, y lo más importante, que aun finalizando la ejecución del programa, QuickBASIC no llegaba a restaurar la paleta de colores original al volver al IDE. Dicha información de color vi que se guardaba en los puertos 0x3c8 y 0x3c9 en VGA. Esos registros se almacenaban en un chip de la gráfica llamado DAC (digital-analog converter). Sí, igual que los DACs de audio.
Recreación del “efecto SCREEN 2”
Seguí tirando del hilo sobre cómo trabajaba internamente la tarjeta gráfica VGA y me topé con un interesante documento de Santiago Romero del año 97 que me dio muchas pistas para poder finalmente cumplir el “deseo” que tuve de pequeño de poder recrear esa paleta de colores rara en DOS sin tener que ejecutar dos instancias de QB45.
Y finalmente lo conseguí. Aunque el resultado no me terminaba de convencer. Efectivamente cambiaba todos los colores del índice 0 a 15 según el depurador, pero del 8 en adelante se visualizaban los últimos 8 colores originales del DAC del VGA. El código era el siguiente:
' Cambiador de paleta de colores
DEF SEG = &HA000 'Establecemos la dirección base 0xA000
OUT &H3C8, 0 'Asignamos 0x00 a la dirección 0x3C8
' Definimos la nueva tabla de colores (R, G, B) en base a 64:
DATA 0,0,0, 63,63,63, 63,63,0, 42,42,0
DATA 21,42,63, 21,42,21, 42,63,21, 63,21,0
DATA 0,63,63, 63,63,0, 42,42,0, 63,0,21
DATA 21,42,21, 42,63,0, 63,21,0, 42,21,0
' Reescribimos los registros del DAC (0x3c9) con los nuevos valores:
FOR I = 0 TO 47
READ N: OUT &H3C9, N
NEXT
Retomando el reto
Hace poco me acordé de este fenómeno (motivo por el cual estoy escribiendo este post) e intenté traducir el código que escribí años atrás en QB45 para realizar la misma recreación en ensamblador por si se trataba de una limitación de acceso del lenguaje BASIC.
Inicié el flamante editor de MS-DOS 6.22, recuperé el archivo BAS que escribí hace unos años, y lo fui traduciendo a código ensamblador para poder luego pasarlo a un .COM mediante el compilador TASM.
Mediante prueba-error, finalmente pude lograrlo escribiendo algo así:
start:
mov dx,03C8h
xor al,al
out dx,al
inc dx
mov si,offset coltab
mov cx,16*3
ciclo:
lodsb
out dx,al
loop ciclo
int 20h
coltab:
db 0,0,0 ; 0 negro
db 63,63,63 ; 1 blanco
db 63,63,0 ; 2 amarillo
db 42,42,0 ; 3 amarillo oscuro
db 21,42,63 ; 4 azul celeste
db 21,42,21 ; 5 verde lima oscuro
db 42,63,21 ; 6 verde lima
db 63,21,0 ; 7 rojo anaranjado
db 0,63,63 ; 8 cian claro
db 63,63,0 ; 9 amarillo
db 42,42,0 ; 10 amarillo oscuro
db 63,0,21 ; 11 fucsia
db 21,42,21 ; 12 verde lima oscuro
db 42,63,0 ; 13 verde lima
db 63,21,0 ; 14 rojo anaranjado
db 42,21,0 ; 15 marrón
end start
Pero volví a obtener el mismo resultado: se cambiaban los colores del 0 al 7, pero del 8 al 15 permanecían los mismos colores brillantes originales de la paleta VGA.
| Colores resultantes | |||||||
|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Al final tiré la toalla y, sin ganas de querer indagar más en el tema (porque en el fondo era una pérdida de tiempo), llegué a la conclusión de que la modificación colores del 8 al 15 no se puede efectuar en modo texto por limitaciones de dicho modo en VGA.
La única posibilidad de cumplir con ese reto mío era la de crear un programa que desde DOS se cambiara al modo BIOS 06h (equivalente a hacer un SCREEN 2 en QB45), y desde ese modo abrir cualquier otro programa para poder ver cómo se alteraban los colores del registro sin tener que consumir mucha memoria, aunque sin poder escoger los colores a nuestro antojo si estábamos en modo texto.
Por lo menos finalmente conseguí hacer algo que hace más de 20 años seguramente me hubiera hecho muchísima ilusión haber conseguido realizar, y en el fondo me sirvió un poco como aprendizaje sobre el comportamiento interno de las tarjetas gráficas CGA y VGA.





