018:utilidades

Microhobby 18. Año II, del 05 al 11 de marzo de 1985

Las sentencias IN y OUT

Jesús Alonso Rodríguez

Nuestro Spectrum no es un sistema cerrado. Puede comunicarse con otros aparatos y periféricos y, por supuesto, recibir datos y órdenes de los mismos. Todo esto se lleva a cabo a través de los «ports» de entrada y salida, cuyo funcionamiento se analiza en este artículo.

Cuando contemplamos el ordenador desde el punto de vista del programador en Basic, realmente no necesitamos tener una idea muy profunda acerca de su funcionamiento. Trabajamos en base 10, calculamos en coma flotante y utilizamos variables olvidándonos de lo que realmente contienen las posiciones de memoria individuales, o de cómo se las arregla el microprocesador para ejecutar el programa que le hemos introducido.

Pero de pronto, nos encontramos en el teclado algunas sentencias de Basic que no tienen nada que ver con las que utilizamos habitualmente, y en cambio, se refieren al propio Sistema en sí; Comandos como OUT y POKE, y funciones tales como IN, PEEK y USR cuya utilización requiere un mayor conocimiento del Sistema.

En esta ocasión, vamos a abordar el estudio del comando OUT y la función IN, que sirven para comunicarse directamente con los periféricos. Para ello, vamos a estudiar primero, cómo se comunica el microprocesador Z-80 con el exterior, y, a continuación, veremos cómo están ordenados los periféricos dentro del sistema que forma el Spectrum.

El microprocesador Z-80 y la memoria, forman el núcleo central de nuestro ordenador; el microprocesador, se comunica con la memoria a través de un conjunto de «cables» que denominamos los «Buses» del sistema. Existen tres buses: el de direcciones, compuesto por 16 «cables» denominados A0, A1, A2,… A 15; el de datos, compuesto por 8 «cables» denominados D0, D1, D2,… D7, y el de control del sistema, compuesto por 6 «cables» denominados «MI», «MREQ», «IORQ», «RD», «WR» y «RFSH». Existen, además, otra serie de «cables» o líneas que controlan el funcionamiento del propio microprocesador y el acceso de otros dispositivos a los buses del sistema, pero en este momento, no nos interesan para lo que pretendemos estudiar.

MREQ significa «Petición de memoria», RD significa «leer» y WR significa «escribir»; si el Z-80 quiere «leer» una posición de memoria, activa las líneas MREQ y RD, y coloca en el bus de direcciones la configuración binaria que corresponde al número de la posición de memoria que desea leer; acto seguido, la memoria le devolverá, a través del bus de datos, la configuración binaria correspondiente al número almacenado en esa posición de memoria. Si lo que deseara fuera escribir un dato, activaría las líneas MREQ y WR colocando la dirección en el bus de direcciones, y el dato a escribir, en el bus de datos.

De forma similar el Z-80 puede leer y escribir datos en los denominados «ports» de entrada/salida». «Port» en inglés significa «puerto», denominación bastante acertada si consideramos que es el lugar donde los datos se mandan al exterior o se reciben del exterior. En el caso de querer acceder a los «ports» el microprocesador activaría la línea IORQ en lugar de la MREQ (IORQ significa «petición de entrada/salida), utilizando de nuevo RD para leer datos y WR para escribirlos.

En este caso, sólo se utiliza la mitad inferior del bus de direcciones, y por tanto, sólo hay 256 «ports» posibles con los que se puede trabajar el Z-80. Cuando el microprocesador desea escribir un dato en un port, activa las líneas IORQ y WR, y coloca en la mitad inferior del bus de direcciones la configuración binaria correspondiente a la dirección del port al que desea acceder, en el bus de datos coloca el dato que desea escribir en ese port y finalmente, en la parte superior del bus de direcciones se coloca el contenido de un registro que puede ser el A o el B dependiendo de la instrucción a la que esté respondiendo el Z-80 en ese momento.

Si lo que desea es leer un dato desde un port, activa las líneas IORQ y RD, y coloca en la mitad inferior del bus de direcciones la configuración binaria correspondiente a la dirección del port del que desea leer; el dato le será entregado desde el port a través del bus de datos; de nuevo, en la mitad superior del bus de direcciones se coloca el contenido de un registro, que podrá ser el A o el B en función de la instrucción a la que esté respondiendo el Z-80 en ese momento. Esta forma de utilizar la mitad superior del bus de direcciones, se revelará muy útil cuando estudiemos la forma en la que se lee el teclado en el Spectrum.

En general, se consideran periféricos todo aquello que no sea el microprocesador o la memoria. Aunque el Spectrum se presente como una unidad compacta, de hecho, alberga en su interior, al menos 4 periféricos: teclado, cassette, altavoz y televisor. Excepto el televisor, todos los demás se manejan a través de los ports de entrada/salida. También se manejan mediante los ports todos los restantes periféricos que se pueden incorporar a la unidad básica, tales como joystick, impresora, microdrives, etc.

Hemos mencionado antes que el Z-80 puede direccionar 256 ports distintos, pero con el fin de no complicar la decodificación, el Spectrum utiliza los bits de la mitad inferior del bus de direcciones, de forma independiente; de este modo, todo el control de las comunicaciones se puede delegar en un solo «chip», la famosa «ULA».

En realidad el Spectrum direcciona todos sus periféricos utilizando, solamente, los cinco primero bits del bus de direcciones de una manera bastante ingeniosa, que vamos a intentar explicar. Por tanto, los bits A5, A6 y A7 se encuentran libres para el usuario, o bien para ser utilizados por dispositivos que no sean los de la marca Sinclair (por ejemplo, el interface de joystyck tipo Kempston se maneja con el bit A5 del bus de direcciones).

Para que la ULA identifique que queremos acceder a un periférico determinado, el bit correspondiente ha de ser «cero». Como el ordenador sólo puede hacer una cosa a la vez, sólo uno de los bits ha de valer «cero», mientras los restantes deberán ser «uno».

El bit A0 maneja el teclado y la entrada EAR cuando se direcciona como entrada (lectura) y el altavoz, la salida MIC y el color del borde, cuando se utiliza como salida (escritura). El bit A2 maneja la impresora, y los bits A1 y A4 se utilizan para los microdrives, la ZX-NET y la salida RS-232.

Las direcciones decimales que hacen que estos bits valgan «cero» mientras los demás permanecen a «uno», se muestran en la tabla 1.

Posiblemente éste sea el port más importante del Spectrum, ya que si se direcciona como entrada, permite leer el teclado y la entrada EAR, y si se direcciona como salida controla el altavoz, la salida MIC y el color del borde de la pantalla.

El teclado se encuentra dividido en ocho semifilas, todas ellas se leen mediante el port 254, pero la ULA sabe qué semifila leer en función de la configuración binaria que se encuentre presente en la mitad superior del bus de direcciones. Aunque el microprocesador sólo puede direccionar 256 ports, desde el Basic podemos pedirle que nos lea un port con una dirección superior a 255; lo que hará el microprocesador será colocar el octeto inferior de nuestro número (convertido en hexadecimal) en la mitad inferior del bus de direcciones, para determinar a cuál de los 256 ports queremos acceder, y el octeto superior lo colocará en la mitad superior del bus de direcciones para aportar a la ULA la información suplementaria que necesite. Por ejemplo: si le decimos LET a = IN 65022, el microprocesador escribirá 254 en la mitad inferior del bus de direcciones, indicando a la ULA que deseamos leer el teclado, y 253 en la mitad superior, para indicarle que es la semifila que va de la «A» a la «G» la que deseamos leer.

En la Tabla 2 se muestran las ocho direcciones de port que nos permiten leer cada semifila del teclado de forma independiente.

Si al leer una semifila no hay ninguna tecla pulsada, el resultado será 255 (todos los bits del bus de datos a «uno»). Cada tecla que se encuentre pulsada pondrá a cero uno de los cinco primeros bits del bus de datos, D0 para la tecla más exterior, D1 para la siguiente y así sucesivamente hasta D4 para la más cercana a la parte central.

El port 254, configurado como entrada, nos permite también leer el estado de la entrada EAR que actuará en este caso, sobre el séptimo bit del bus de datos, es decir, D7.

Si utilizamos el port 254 como salida, podremos controlar con el bit D4 el altavoz, con D3 la salida MIC y con D2, D1 y D0, el color del borde de la pantalla. Por ejemplo, si tecleamos el comando OUT 254,3 el borde se pondrá de color magenta; pero recuerde que éste es sólo un color temporal, volverá a su color original cuando pulse cualquier tecla. OUT 254,16 producirá un chasquido en el altavoz mientras el borde se pondrá de color negro.

La función IN del Basic nos permite acceder directamente a los ports; su forma general es: IN dirección

Recuerde que la dirección puede ser superior a 255, por ejemplo, cuando pretenda leer una semifila del teclado.

No olvide que se trata de una función, por lo que teclearla de forma directa como un comando, no tiene sentido. Como toda función, le dará un resultado, que será el valor entregado al bus de datos por el port correspondiente. Este valor deberá asignarlo a una variable o incluirlo en una expresión, por ejemplo: LET a = IN 65022 o bien: IF IN 65022 = 255 THEN GO TO 100. Encontrará que IN es muy similar a PEEK en cuanto a su sintaxis.

Resulta muy útil la función IN con la dirección 223, ya que nos permite leer el dato entregado por un joystick con interface tipo Kempston.

Para escribir un dato en un port desde el Basic, hacemos uso del comando OUT; su forma general es: OUT dirección, dato

En este caso la sintaxis es muy similar a la del comando POKE. Tanto la dirección como el dato deberán ser números comprendidos entre «cero» y 255.

Tabla 1
Bit Dirección decimal Configuración binaria
A0 254 00000000 111 11110
A1 253 00000000 111 11101
A2 251 00000000 111 11011
A3 247 00000000 111 10111
A4 239 00000000 111 01111
A5 223 00000000 110 11111
Tabla 2
Dirección de port Semifila leída Configuración binaria
65278 (FEFE) Caps shift a V 11111110 111 11110
65022 (FDFE) A a G 11111101 111 11110
64510 (FBFE) Q a T 11111011 111 11110
63486 (F7FE) 1 a 5 11110111 111 11110
61438 (EFFE) 0 a 6 11101111 111 11110
57342 (DFFE) P a Y 11011111 111 11110
49150 (BFFE) Enter a H 10111111 111 11110
32766 (7FFE) Space a B 01111111 111 11110
  • 018/utilidades.txt
  • Última modificación: d/m/Y H:i
  • por miguel