Blogia
Las Pequeñas Paranoyas de Motagirl

Acceso a ROM para obtener los patrones de bits de los caracteres

¡Ay qué bonicas son las prácticas de  Periféricos cuando comienzan a funcionar!

Ya os comenté el otro día cómo acceder a memoria de video y juguetear con ella, y el tema de hoy está bastante relacionado con ello (siempre basado en TurboC sobre MS-DOS, si usais otros compiñadores compiladores y no tira... no es mi culpa :P)

Bueno, resulta que cuando escribimos un  carácter en la memoria de video, por ejemplo, la ’M’ de motagirl, no estamos escribiendo en realidad esa M, sino un  77, que es su código ASCII  (podeis consultarlos todos aqui).

En realidad, para lo que sirve ese  77 es para indexar una tabla presente en la BIOS, donde se encuentra  un patrón de bits para cada carácter (1 indica pixel relleno, 0 indica pixel vacío). La tabla tiene 256 carácteres,y cada carácter consta de 16bytes, siendo la M tal que así:

00000000
00000000
01100011
01110111
01111111
01111111
01101011
01100011
01100011
01100011
01100011
01100011
00000000
00000000
00000000
00000000

(Si os alejais un poco se ve algo mejor)

¿Y cómo  podemos acceder a la tabla? La dirección nos la puede dar una función de la BIOS. Para invocarla,  es  necesario poner unos determinados códigos en los registros de la CPU (ax: 0x1130, bx: 0x0600), llamamos  a la función usando una interrupción software (para la Bios de video, la 0x10) y esta amablemente nos dejará los valores deseados en otros registros de la CPU (es:  segmento, bp: offset).  Para ello, creamos  una estructura de tipo REGPACK, a la que llamaremos rp y que actuará como  pseudoregistros (y que no se nos olvide el #include del dos.h :P) :

struct REGPACK rp;
rp.r_ax=0x1130;
rp.r_bx=0x0600;
intr(0x10,&rp);

Y esto nos dará , como dije  antes, la dirección de la tabla de patrones de bits de los caracteres, con el segmento en ES y el offset en BP.

Ahora sólo necesitamos montarnos nuestro punterillo a dicha dirección:

char* lista = (char *)MK_FP(rp.r_es,rp.r_bp);

Y ya tenemos nuestro puntero mágico apuntando al inicio de la tabla.¿Y para acceder a una posición concreta? Bueno, supongamos que quiero ir a la letra M, a la que, como  dije antes,  corresponde el código 77. Pues simplemente tendría que "saltar" los 76 caracteres anteriores,  a 16 bytes cada uno. Podría hacerlo  así:

lista = (lista+77*16);

Con eso estaría apuntando al inicio  de los 16*8 bits de los que consta el patrón de la M. (Nótese que estamos usando un puntero a char, es decir, que cada vez que avancemos  una posicion (por ejemplo, lista= lista+1) estaremos avanzando 8bits)¿Y cómo "pinto" el patrón de bits? Esto ya es más chispeante ^^

Necesitamos crearnos una bonita función o equivalente que devuelva un determinado bit (0 o 1) de un char (1byte, 8bits). Un ejemplo  de cómo hacerlo podría ser esto:

(*p & (1<>n;

que devuelve el enésimo (n) bit de un char* p, usándo máscaras y desplazamientos.

Entonces, para obtener (por pantalla,o a un archivo) el patrón de bits, simplemente debemos apuntar a la letra deseada (lista = (lista+77*16);), y recorrer sus 16 filas mostrando  bit a bit las 8 columnas (las columnas en orden decreciente, por que si no sale como reflejado en un espejo). Dicho así queda un poco raro, pero en  realidad cada carácter no es más que un churro  de 16bytes que tenemos que sacar por pantalla en cachos de 8 en 8 bytes.

Si alguien tiene curiosidad, he subido un archivo con el volcado de todos los patrones aquí. (Hecho a base de un bucle de 256 (caracteres), otro anidado de 16 (filas) y otro más anidado , de 8 (columnas)) . Los primeros treintayalgún patrones no tienen mucho sentido porque son caracteres no imprimibles, las letras  ·de verdad"se ven más claras :)

En breve (aka cuando lo termine xD) colgaré otro post explicando cómo pasar esa tabla a RAM,  modificarla con  tus propios caracteres customizados,  y toquetear las interrupciones para que los patrones usados sean los tuyos y no los de la BIOS :)

[Siguiente capítulo: Modificación de los patrones de bits de los caracteres]

4 comentarios

caxarro -

Y lo que vas a flipar cuando os diga, ale hacerme un sistema FAT hermosos¡ ahi es cuando uno empieza a verselas putas jajajaja pero con calma claro. Si necesitas ayuda cuando llegue ese momento me tienes en el google talk¡¡ ya saps. Que vaya be¡¡ :P

meloncito -

Ché, gracias por lo de consultar los bits. Yo habia hecho una función para pasar de decimal (mediante un cast) a binario y no rulaba del todo bien.

La práctica ya la tengo casi hecha, lo unico que me ha tocado los bowlins es que la copia la he tenido que hacer en memoria estática (char copia[4096]), ya que si lo hacía con el malloc, me petada asignando los valores.

Lo hacía asi:

copia=(char *) malloc (256*16*sizeof(char));

Nada, y petaba : /, pero bueno, da igual, estar está en RAM xDD

Debiarko -

Una autentica parra hacer un more en terminal con fondo negro y el txt y no soltar el intro.

Debiarko -

Flipa neng.