Blogia
Las Pequeñas Paranoyas de Motagirl

Modificación de los patrones de bits de los caracteres

[Capítulo anterior: Acceso a ROM para obtener los patrones de bits de los caracteres]

Hace unos días os conté cómo acceder a ROM (la BIOS de toda la vida) para coger los patrones de bits de los que están formados los caracteres que se escriben en la memoria de  video. Esto puede ser divertido, pero... también un poco estático, ¿no?

El experimento ganaría en posibilidades si pudiésemos modificar esos patrones para crearnos nuestras propias fuentes. Vale, sí, sería una cosa muy artesanal y a bajo nivel, bit a bit y todo eso, pero... ¿acaso teneis algo mejor que hacer?   xD

Yo no voy a crear aquí un juego de fuentes entero porque no estoy tan enferma (de momento), sino que me voy a conformar con ponerle una rayita encima a la letra A (sí, igualito que en el enunciado de la práctica 4 de Periféricos, soy poco original).

Así, de primeras, no  podemos  modificar los patrones de bits porque están en ROM, que como su propio nombre indica, es Read Only Memory. Así que el primer paso es copiar esa lista de 256 caracteres * 16 bytes/caracter de la ROM a la RAM. ¿Como? Creando una variable char* de ese tamaño (con malloc), y asignándole byte a byte el contenido de la variable (también char*) original que contiene la lista de patrones en la ROM (esto lo expliqué aquí)

Ahora, puedo añadir todas las modificaciones que desee, puesto que mi tablita ya está en memoría escribible. Como  dije, añadiré una rayita sobre la A. Puesto que la A es el carácter 65, avanzo hasta su posición. Los 8 siguientes bytes son cada una de las "filas" de pixeles de las que está formada la A, así que como quiero la rayita ENCIMA de la A  (en el primer byte), no necesito desplazarme "hacia abajo" (sumando entre 1 y 8 al desplazamiento de 256*16):

    *(listaRAM+65*16)=255;

255 es en hexadecimal lo que en binario viene siendo 11111111, o sea, en el idioma de los pixeles (xD) una línea.

Ahora que ya tenemos nuestra lista con la modificación, lo que queremos es decirle a la tarjeta dónde está el nuevo juego de carácteres, para que "olvide"   el viejo y use el nuestro (modificado). Esto tenemos que hacerlo con interrupciones en ensamblador, o sea que necesitareis un TurboAssembler o equivalente.

El código sería el siguiente:

    asm push ax;
    asm push bx;
    asm push cx;
    asm push dx;
    asm push es;
    asm push bp;
    asm mov ax, 1110h;
    asm mov bx, 1000h;
    asm mov cx, 0100h;
    asm mov dx, 0;
    asm les bp, listaRAM;
    asm int 10h;
    asm pop  bp;
    asm pop  es;
    asm pop  dx;
    asm pop  cx;
    asm pop  bx;
    asm pop  ax;

Ese cacho de código viene siendo una llamada a palo seco a una señora interrupción software. En primer lugar, guarda los  registros del procesador en la pila (push). Luego guarda en AX, BX, CX y DX los valores predeterminados para "decirle" a la interrupción qué es lo que quiere. Después, se llama a la interrupción  en  sí con  "int" (la interrupción 10h, con 1100 en  AX, que es esta), y finalmente devuelve a su sitio los registros del procesador (pop), para que pueda seguir su curso.  Y "asm" indica al compilador que lo que sigue es ensamblador, así que con  eso llama al TurboAssembler.

Tras compilar y linkar, ejecutamos, y esto es lo que obtenemos: Todos los caracteres "A" de la pantalla se convierten en "A con palito" (aka "A customizada") hasta que hacemos un cls.  ¿A que mola? ^^

Un par de fotos del "antes" y "después" de la operación:

Antes

Después

Por alguna  misteriosa razón, funciona perfectamente sobre DosBox,  no así con el símbolo de sistema (cmd). No me pregunteis por qué, pero llevo una semana volviéndome loca con esto, así que antes de moriros de asco... probadlo con DosBox xD (A mí la idea me la dio el profesor, porque hasta este momento había estado usando cmd) No he probado con otros emuladores, pero si alguien se ha aburrido y lo ha hecho, podría darnos feedback  :P

6 comentarios

jordan 12 -

The reply is extremely easy. It's allin how they perceive their troubles. Yes, each and every living person has troubles. A problem-free everyday life is definitely an illusion-a mirage inside desert. Accept that simple fact.

Nike Shox Rivalry -

Friendship will be thinking about caring, written in regards to write in the sincere greeting will bless, written in the beautiful words, words written in my heart, I will write on the blessings, wish your happy, happy friends long company!

mgo3 -

Vale, tan sencillo como keyb sp, jeje...

mgo3 -

Hola, ey! muchas gracias por todos tus post sobre periféricos, ayudan bastante... un temita sobre dosbox: sabéis de alguna guía de instalación/configuración o algo? porque me lo instalo y como que los caracteres están cambiados, es decir, como si el teclado fuera el de otro idioma o algo...

Gracias!
See u

motagirl2 -

El secreto está en el Kernel =^_^=

maeghith -

"""
Por alguna misteriosa razón, funciona perfectamente sobre DosBox, no así con el símbolo de sistema (cmd).
"""

Por que cmd.exe no es un DOS, sino el shell de linea de comandos de NT (que es un kernel distinto al de los sistemas DOS). En cambio DOSBox es un emulador completo de una máquina con un sistema DOS.

Creo que XP aún tiene un COMMAND.COM, aunque no se como se comportará con el acceso directo a interrupciones que estás haciendo en las prácticas. También, según acabo de mirar en wikipedia, puedes probar con ntdvm.exe (NT DOS Virtual Machine, de la que jamás había oido hablar, pero por lo que dicen ahí puede que haya alguna mínima probabilidad de que funcione), aunque si ya te funciona con DOSBox, tampoco le des más vueltas.