# IBM PC ROM BIOS

El IBM ROM BIOS, IBM BIOS o ROM BIOS era el BIOS del computador IBM PC. El BIOS residía en una memoria ROM de la tarjeta madre del IBM PC y ocupaba 8 KiB. El BIOS realizaba un Power On Self Test (POST)), donde se revisaban e inicializaban algunos componentes del computador, se inicializaba y ponía operativo al BIOS y al final se ejecutaba el Boot Strap Loader, el cual, cargaba en memoria RAM y ejecutaba el programa que residía en el primer sector del disquete, o en caso de no poder hacerlo, cargaba al IBM Cassette BASIC, la versión de BASIC que residía en la ROM de la tarjeta madre.
En el IBM PC Technical Reference Manual (Manual de Referencia Técnica del IBM PC), había un listado completo del código fuente en assembler del BIOS. Este listado del código fuente fue usado con ingeniería inversa y técnicas de cuarto (también conocidas como Diseño en sala limpia) para realizar clones legales del BIOS. Con estos BIOS se hizo posible el surgimiento de la industria de los clones compatibles con el IBM PC que llega hasta nuestros días.

## Power On Self Test (POST)

Cuando se enciende el computador prácticamente nada está funcionando. No funcionan, la tarjeta de video, ni el teclado, ni la memoria RAM, ni el controlador de interrupciones, ni el controlador de DMA, ni el temporizador programable de intervalos, etc. Ni siquiera las funciones del propio BIOS están operativas ya que este todavía no se ha inicializado. Solo está funcionando el CPU y también se puede leer el contenido de la memoria ROM.
En el IBM PC, lo primero que ejecuta el CPU es el Power On Self Test (POST), y es aquí donde se iban revisando, iniciando, y poniendo operativos, uno a uno, cada uno de los componentes del PC.
El IBM PC tenía un procesador Intel 8088. Por diseño, la primera instrucción que realizaba el procesador 8088 era la que estaba localizada en la dirección de memoria FFFF:0 (en hexadecimal), la cual se encontraba en el ROM del BIOS del IBM PC. En la dirección FFFF:0 estaba una instrucción JMP que saltaba al inicio del código del Power On Self Test. El código del Power On Self Test revisaba el CPU, la integridad del ROM donde estaba contenido el propio BIOS y la de los 4 ROM del IBM BASIC, la memoria RAM; se revisaban e inicializaban los principales circuitos integrados del IBM PC, como el controlador de DMA 8237, el controlador de interrupciones 8259, el timer 8253, el controlador de video 6845, la tarjeta de video, el teclado, la interfaz para casete, la unidad de disquete, los puertos seriales y paralelos, en caso de que los hubieran.
También se inicializaban áreas bajas de la memoria RAM con tablas, datos y áreas de trabajo destinadas a ser usadas por el BIOS, así como también las direcciones a que apuntaban los vectores de interrupción del 8088, para que apuntaran a rutinas que implementaban el BIOS, a tablas de parámetros, y al código de inicialización del ROM BASIC (IBM Cassette BASIC)). Al direccionar los vectores de interrupción para que apuntaran a las varias rutinas correspondientes del BIOS y sus tablas de datos, y luego activar las interrupciones del procesador, era cuando el BIOS era activado y podía ofrecer su funcionalidad.
Una vez finalizado el Power On Self Test, se ejecutaba el Boot Strap Loader (BSL) para comenzar la secuencia de bootstrap.

## Boot Strap Loader

El Boot Strap Loader es el encargado del bootstraping en el IBM PC y los posteriores computadores personales de IBM. En el IBM PC, primero determinaba si había una unidad de disquete con un disquete insertado. En caso de haberlos, trataba de leer el primer sector del disquete (el sector de arranque) y copiaba su contenido en la posición de memoria BOOT_LOCN (dirección 0000:7C00 en hexadecimal) para ejecutar el programa que se localizaba allí. En caso de no haber unidad de disquete, o no haber un disquete insertado en ella, o haber fallado la lectura del disquete, o cualquier error en el proceso, se ejecutaba el IBM Cassette BASIC que residía en la ROM del sistema, y entonces aparecía la pantalla inicial del BASIC. Esto último diferenciaba los computadores personales de IBM de los clones que aparecieron después. Los clones no tenían (ni tienen) una ROM de BASIC y en caso de no poder cargar en memoria el primer sector del disco muestran un mensaje de error.
En el primer sector del disquete (formateado con el PC DOS), se encontraba un pequeño programa que era cargado por el Boot Strap Loader a la dirección de memoria 0000:7C00 y luego le pasaba el control. Este programa podía desplegar un mensaje de error en la pantalla, (en caso de ser un disco de datos), o era la primera secuencia de código que se ejecutaba para cargar al sistema operativo PC DOS a memoria y ponerlo en funcionamiento, (en caso de ser un disco del sistema), iniciando así el bootstraping del sistema operativo. Ciertos programas comerciales venían con el primer sector diferente, y este contenía código propio para propósitos especiales, como por ejemplo, un mecanismo de protección anticopia. También, cuando aparecieron los virus de computadora, este primer sector era una de las áreas comunes de ataque. Al residir el virus en el sector de arranque, era lo primero que se cargaba en la memoria del computador cuando este se encendía, y quedaba residente allí para, tal vez, contaminar todo disquete que se insertara en la unidad, replicándose en sus sectores de arranque,

## Funciones del BIOS

El BIOS tenía funciones básicas de entrada/salida para el teclado, la pantalla, la impresora, el puerto de comunicaciones RS-232, el manejo de las unidades de disquete y la interfaz para casetes, entre otras. Adicionalmente había rutinas que respondían a interrupciones de dispositivos del hardware. Había también una función para llamar al BASIC en ROM.

### Funciones

Las funciones del BIOS se accedían invocando interrupciones por software para el CPU del IBM PC, el Intel 8088. Esto hacía que el CPU generara una interrupción y fuera llamada la función del BIOS a la que apuntaba el vector de interrupción correspondiente. Los parámetros a la función se pasan por medio los registros internos del CPU (AX, BX, CX, DX, etc), y en caso de que una función tuviera que retornar algún valor, también lo hacía mediante los registros del procesador.
La siguiente es una lista de las funciones del BIOS. (Los números de las funciones están en hexadecimal, y representan el número de interrupción que se necesita llamar por software desde un programa):
* 05 - Imprime el contenido de la pantalla (Print Screen)
* 10 - I/O para el video
* 11 - Determinación del hardware opcional instalado
* 12 - Determinación de la cantidad de memoria RAM
* 13 - I/O para la unidad de disquete
* 14 - I/O para el puerto serial RS-232
* 15 - I/O para la unidad de casete
* 16 - I/O para el teclado
* 17 - I/O para la impresora
* 18 - Ejecuta al IBM PC ROM BASIC
* 19 - Boot Strap Loader
* 1A - Retorna o ajusta la hora

### Interrupciones generadas por el hardware

El BIOS también respondía a algunas interrupciones de hardware, generadas por dispositivos como el teclado, el temporizador, y el controlador de la unidad de disquete. Las señales de los dispositivos llegaban el controlador de interrupciones Intel 8259.
* 08 - Time of day (18,2 veces por segundo), generado por el canal 0 del timer 8253. Usado para poder mantener la hora del día.
* 09 - Interrupción del teclado. Generado por el teclado al presionar o soltar cada tecla
* 0A - No usado
* 0B - No usado
* 0C - No usado. Reservada para comunicaciones (RS-232)
* 0D - No usado
* 0E - Generado por el controlador de unidades de disquetes
* 0F - No usado. Reservada para la impresora
En computadores posteriores al IBM PC se fueron agregando más dispositivos de hardware que generaban interrupciones.

### Interrupciones generadas por el BIOS

El BIOS generaba las siguientes interrupciones:
* 1B - CTRL-BREAK. Generado cada vez que se ejecutaba la secuencia CTRL + BREAK en el teclado
* 1C - Timer Tick (18,2 veces por segundo). Generada cada vez que el BIOS recibía la interrupción 08 (ver arriba)
Estas interrupciones inicialmente son respondidas por el propio BIOS con una instrucción IRET (Interrupt Return), (Retorno de Interrupción), y se retornaba inmediatamente sin hacer nada. Un programa podía hacer que estas interrupciones apuntaran a rutinas internas y así poder procesarlas para determinados propósitos.

### Tablas

El BIOS tiene diferentes tablas y áreas de datos, necesarias para poder realizar sus funciones. Algunos vectores de interrupción son usados para apuntar a estas tablas:
* 1D - Tabla con parámetros de inicialización para el controlador de video
* 1E - Tabla con parámetros para la unidad de disquete
* 1F - Tabla con los patrones de bits de los primeros 128 caracteres ASCII Extendido para usarse para desplegar texto y caracteres en los modos gráficos de la tarjeta CGA
Nótese que este no es el uso habitual de los vectores de interrupción. Un vector de interrupción normalmente apunta a una sección de código, no a tablas con datos. Una llamada errónea a estas interrupciones generaría que el computador se estrellara, pues se tratarían de ejecutar los datos de las tablas como si fueran código.

#### Tabla de gráficos para la generación de caracteres

El vector de interrupción 1F, apunta a una dirección dentro del BIOS donde se encuentra una tabla usada para la generación de caracteres en los modos gráficos.
Cerca del final del ROM del BIOS, había una tabla que se usaba, por las funciones de video del BIOS, para la generación de caracteres en los modos gráficos. Esta tabla contenía los patrones de bits de los primeros 128 caracteres del código ASCII extendido del IBM PC, y era usada para generar el texto, dígitos, símbolos, y caracteres especiales, en los modos gráficos de la tarjeta de video CGA (para las sus modos gráficos de 320x200 y 640x200). Estos 128 caracteres correspondían a los del código ASCII estándar, pero mientras que los caracteres del 0 al 31 del ASCII son caracteres de control no imprimibles, en esta tabla, IBM había aprovechado esos códigos del 0 al 31 para usarlos para generar caracteres y símbolos gráficos especiales, que a diferencia del ASCII normal, sí generaban una imagen.
En la tabla del BIOS no estaban representados los patrones de bits para los caracteres del 128 al 255 del ASCII extendido de IBM, así que en los modos gráficos no podían desplegarse esos caracteres mediante el BIOS. En los modos de texto sí se generaban porque ellos estaban definidos en una ROM interna en cada una de las tarjetas de video, CGA y MDA, que contenía los patrones de bits de todos los 256 caracteres del ASCII extendido.

## Área de datos del BIOS

El IBM ROM BIOS tenía un área de datos en RAM que iba desde 0040:0000 hasta 0040:00FF. Donde se encontraban el estado y otros datos sobre dispositivos del sistema y era usada por las funciones del BIOS para poder realizar sus tareas. En esa área de datos se encontraba lo siguiente:
* Datos de configuración del hardware. Contenía las direcciones de hasta 4 puertos seriales y 4 puertos paralelos, información del hardware y cantidad de memoria RAM instalados, y cierta información del estado de inicialización
* Datos del Teclado. Contenía el buffer del teclado (16 caracteres), el estado de varias teclas como ambas teclas de CTRL y ALT, las teclas INS, NumLook, CapsLook, etc, y un byte para almacenar el carácter generado con un código de 3 dígitos usando ALT + teclado numérico
* Datos del Disquete. Contenía el estado de la disquetera y de su controlador
* Datos del Video. Contenía información de estado de la tarjeta de video activa
* Datos del Casete. Contenía información de estado de la unidad de casete
* Datos del Timer. Contenía un contador de Ticks, (que ocurría 18,2 veces por segundo), desde que el computador se encendía. Servía para determinar cual era la hora del día.
* Datos del Sistema. Contenía información que indicaba si se había hecho un CTRL+BREAK y si se estaba reseteando la máquina (con CTRL+ALT+DEL).
En la dirección 0050:0000 había un área de datos extra.
Adicionalmente había un área localizada entre 0030:0000 hasta 0030:00FF donde se encontraba un stack para uso durante el POST y que estaba activo cuando se realizaba el Boot Strap Loader y este le pasaba el control al programa localizado en el primer sector del disquete. Este programa podía seguir usándola o crear su propia área de stack.

## Versiones

La primera versión del IBM PC ROM BIOS está fechada el 24/04/1981, la cual salió con el IBM PC original del 12/08/1981. Luego hay una versión del 19/10/1981 y otra del 27/10/1982. Las primeras dos versiones no escaneaban las áreas de ROM BIOS en busca de ROMs de extensión así que no podían cargar desde un disco duro, o usar dispositivos que dependieran de las ROM BIOS de extensión.

### Versiones posteriores

En versiones posteriores, para los computadores personales de IBM que siguieron al IBM PC, como el IBM XT, IBM AT, la línea PS/2, etc, y de los computadores clones, se agregó más funcionalidad al BIOS.
En el IBM XT (y computadores posteriores) apareció funcionalidad para trabajar con unidades de disco duro, que comenzaron a venir de una manera estándar en el IBM XT y que el IBM PC no tenía, y se agregó la capacidad de cargar el sector de arranque desde el disco duro además de la que ya existía para cargarlo desde el floppy.