|
|
|
En esta sección
veremos como programar el teclado, que hoy en día es un elemento
imprescindible en la computación.
Si alguna vez han intentado mover una imagen por la pantalla, por ejemplo un muñeco en un juego, y quisieron moverlo en diagonal con los cursores, seguramente no han podido ya que no habrán tenido idea de como hacer para detectar más de una tecla simultáneamente. Pues bien esto es lo que veremos ahora. Cuando pulsamos una tecla hasta que tenemos el valor ASCII suceden muchas cosas dentro de nuestro PC. Cuando se pulsa una tecla, hay un chip que está en nuestro teclado llamado 8048, el cual detecta un cambio de corriente y gracias a esto, el chip será capaz de calcular la posición de la tecla. Según donde se encuentre ubicada la tecla el chip dará un código u otro, el cual será transmitido al computador a través del puerto 60h. Alguien puede pensar que estos códigos son los ASCII, pero no es así, ya que estos códigos no tienen nada que ver con los que nos devuelven. A estos códigos se es conocen por el nombre de SCAN-CODES y por regla en todos los teclados son iguales. El encargado de recoger este código es otro chip que se conoce con el nombre de 8042 y es el que genera la IRQ1, la cual tiene una rutina ubicada en la interrupción 9h, y lo que hace es leer el código de la tecla que lee como hemos dicho antes del puerto 60h y después dicha rutina lo que hace es convertir ese código a ASCII y ponerlo en el buffer del teclado que se encuentra en los primeros 64 Kb de la memoria junto con otras variables de la BIOS y que tiene una longitud de 16 bytes o caracteres. Es por eso que cuando instalamos el famoso “keyb sp” en el computador nos sale la “ñ” o la “'ç” al apretar las teclas correspondientes, ya que lo que hace no es más que sustituir la rutina original (la de fábrica) por otra propia encargada de poner cada carácter ASCII donde le corresponde. Cuando ya tenemos el código ASCII (las rutinas de la BIOS se encargan de convertir el código a ASCII) lo podremos leer a través de las funciones de la interrupción 16h. Pero esto a nosotros no nos interesa mucho, ya que no podremos leer más de una tecla a la vez con estas funciones y además sólo nos informan si una tecla ha sido o no pulsada. Lo que tendremos que hacer será sustituir el controlador actual de la interrupción 9h, por uno propio que nos irá informando de las teclas que hay sido pulsadas en cada instante que nosotros deseemos. Para poder colocar nuestra nueva rutina, lo que tendremos que hacer es mediante la interrupción 21h de los servicios del DOS, sustituir nuestra rutina por la actual, y esto lo haremos con la función 25h cuyos argumentos son en AH el número de subfunción (25h) y en AL en número de interrupción que queremos cambiar (09h) y finalmente en DX el offset a dicha interrupción. Pero antes deberemos salvar con la función 35h de la misma interrupción los vectores de la interrupción actualmente instalada, para poder restaurarlos al finalizar nuestro programa. INTERRUPCION 21h Función 25h Entrada: ah
= 25h
Función 35h Entrada: ah
= 35h
Salida:
es:bx = Un puntero de tipo far, la actual rutina de la interrupción
En lenguaje C esto lo realizaríamos
con las funciones que nos proporciona nuestro compilador, ya que es un
lenguaje de alto nivel, no hace falta que siempre vayamos a llamar
a la interrupciones mediante ensamblador, ya que hay funciones que hacen
lo mismo, a través de las interrupciones, pero de una forma más
fácil para el programador. Nosotros, por ejemplo, lo haríamos
de la siguiente forma:
Como ven, lo que hacemos es declarar una función de tipo interrupción para guardar allí los antiguos vectores que sustituiremos después por los nuestros y después los hemos salvados en este, pues los cambiamos por nuestra nueva interrupción, pero ¿qué es lo que hará esta interrupción? Controlará el teclado y nos informará de que teclas se están pulsando. Para ir resulte bien, la rutina tendrá que estar escrita en ensamblador, así conseguiremos mayor velocidad (mayor respuesta del teclado). Lo primero que haremos será leer del puerto 60h, ya que si se ha ejecutado esta interrupción es porque hay un código que debemos recoger, por que se ha pulsado una tecla. Una cosa muy importante que no hemos dicho, es que hay dos tipos diferentes de códigos: los códigos Release y los códigos Make. Cuando pulsamos una tecla el teclado envía un código, pero ¿cómo sabemos cuando se ha soltado una tecla?, pues lo sabemos por que cuando se suelta una tecla, el teclado también nos envía un código. Esta característica nos será de grandísima utilidad, ya que lo que haremos será, crearnos una tabla de bytes: unsigned char tecla[128]; Cada posición corresponderá a una tecla, y que pondremos en nuestra nueva posición a uno. Es por eso que en la primera rutina que vimos, colocamos todos estos valores a cero lo que significa que ninguna tecla está pulsada. Si el código es MAKE querrá decir que se ha pulsado una tecla, y por lo tanto pondremos a uno la posición que nos indique el código y si por el contrario se trata de un código RELEASE pues pondremos a cero dicha posición. Más adelante veremos una lista donde se puede observar a que tecla corresponde cada código, pues solo tenemos que crear una lista de constantes para cada valor. Por ejemplo si queremos detectar la tecla espacio haríamos lo siguiente: if(tecla[KEY_ESPACIO]==1) tecla_apretada(); o por ejemplo poner pixeles mientras se apreta la tecla Enter: while(tecla[KEY_ENTER]==1)
Como hemos dicho, leemos un código y ponemos en la tabla un 0 o un 1 dependiendo de si se trata de un código Make o de un Release. Pero ¿cómo sabemos si es uno o otro? Pues si el valor leído es mayor de 128 se trata de un código RELEASE, es decir se ha soltado una tecla, y si no pues se trata de un código MAKE. Ahora veremos como nos quedaría
la rutina en ensamblador para la nueva interrupción:
Una cosa que no hemos dicho es que al acabar la interrupción deberemos enviar el valor 20h al puerto 20h, para que así sepa que hemos terminado, es muy importante hacer esto, ya que si no, no nos funcionará. Haz click aquí para ver una lista de los códigos SCAN más utilizados.
Ejemplo Librería gráfica:
vgalib.h
En el ejemplo se podrá ver la utilización
de las nuevas rutinas para manejar el teclado. Con el movimiento de los
cursores de podrá mover un punto o dibujar una línea. Presionando
Enter se borrará la pantalla.
|