La historia comienza en este hilo (NOTA: probablemente no funcione, así que pondré la versión del Wayback Machine)
https://web.archive.org/web/20151021100 ... &order=ASC
Hoy llegó el Spectrum, y pude comprobar que, efectivamente, el teclado no respondía, aun estando perfectamente.
Probé otra ULA en lugar de la que tenía, y el teclado volvió a la vida.
¡Ea, otra ULA a la porra! pensé, pero... ¡qué raro! sólo le falla la lectura de teclado. El teclado, aunque es leído por la ULA, es un periférico tan sencillo que puede implementarse "fuera" de ella.
Así que probé con mi interfaz de teclado PS/2 (versión externa de Ben Veersteg), y con él, sí que pude teclear.
Como se puede observar, incluso pude cargar un juego y jugar a él. Esto significa que la ULA no tiene problema para leer el bit 6 del puerto de teclado (254) que es el que contiene el estado del bit de EAR.
Tampoco tuvo problemas para generar sonidos o cambiar el color del borde. Aparentemente, el único fallo está en los cinco bits menos significativos que la ULA entrega al Z80.
Pensé que podría ser el transistor que está encima del Z80 (esta placa es una issue 2). Ese transistor es el decodificador del puerto 254, y si no funciona, la ULA no es seleccionada por el Z80 y no se puede leer ni escribir en ella, pero rapidamente lo descarté porque al arrancar, el borde pasa del color que estuviera, a blanco. Es decir, el Z80 puede escribir en la ULA, con lo que el transistor debe funcionar.
También pensé en un acoplo demasiado débil entre el bus de datos de la ULA y el del Z80. Es decir, que el valor "0" que fuerza la ULA no sea lo suficientemente "fuerte" para que el Z80 lo lea, a través de las resistencias que desacoplan ambos buses. Probé esta ULA en otros Spectrum's pero en ninguno funcionó satisfactoriamente.
La única solución: "bypassear" la ULA. Es decir, desconectar la ULA del teclado, y hacer que la lectura del mismo la haga un circuito externo.
EL circuito debe ser un buffer triestado de 5 bits. A la entrada de cada buffer habrá una de las 5 lineas del teclado (KB0 a KB4). A la salida, los bits D0 a D4 del bus de datos, en el lado del Z80 (es decir, en el bus de datos del Z80, no de la ULA). Un buffer conecta KB0 con D0, otro conecta KB1 con D1, y así sucesivamente.
La condición de triestado de los cinco bufferes es controlada por la combinación de señales que hacen que el Z80 quiera leer algo de la ULA. Esa combinación (la más sencilla) es cuando A0 vale 0, IORQ vale 0, y RD vale 0. La combinación de A0 y IORQ ya está presente en una de las patas del transistor que se "acuesta" encima del Z80, pero he preferido usar las señales "originales". Así, cuando (A0 or IORQ or RD) valga 0, entonces deben abrirse los bufferes para que el dato contenido en KB0-KB4 salga a D0-D4.
Para implementar este sencillo circuito, he recurrido a una pequeña GAL. Es todo lo que necesito. La pondré en un zócalo, soldado a una placa pequeña, de la que pueda coger fácilmente puntos de soldadura para unirlo a diferentes partes de la placa del Spectrum.
Para el zócalo, como no tengo uno de 10+10, uno un zócalo de 7+7 con otro de 4+4. Me sobran dos pines, pero no pasa nada.
Soldado queda así. Dejo un poco de espacio para poder soldar los cablecillos que van a cada pin.
Lo sueldo todo en la cara de pistas, para dejar la cara de componentes vacía. De esa forma queda "lisa".
Y me permite poner todo el circuito simplemente "echado" encima de cualquier parte donde haya suficiente sitio, sin temor a que al apoyarlo haga contacto con algo (apoyamos sobre lo que sería la cara de componentes, que es todo baquelita). Por ejemplo, aquí, encima de los chips de multiplexión de direcciones:
Cableo todo el circuito: con cable verde, desde el conector de 5 pines de teclado, hasta los pines que he definido como entradas de los cinco bufferes. Luego, desde las salidas de los bufferes hasta el terminal derecho de las resistencias R1 a R5, que llevan los bits D0 a D4 del bus de datos del procesador. Con cable azul, alimentación de 5V y masa. Con cable negro, las señales de control de triestado (IORQ, A0 y RD).
El fallo que tiene la ULA, en concreto, consiste en que lo que tendrían que ser entradas de señal, actúan como salida de señal, manteniendo todas las líneas de teclado a 5V (1 lógico) por lo que no se detecta nunca una tecla pulsada. Debe haber algún cortocircuito interno que haga que se envíe tensión por esos pines, lo cual no debería pasar.
Para evitar problemas, al poner de nuevo la ULA en su sitio, dejamos los cinco pines del teclado "al aire". En la foto se ven tres de ellos. Los otros dos están al otro lado.
¡Y ya está! Con la ULA "inutilizada" para leer el teclado, dicha gestión corre a cargo de este pequeño circuito, que podría considerarse un "cachito de ULA". Ahora el teclado funciona sin problemas.
A modo de referencia, dejo el código fuente del archivo de configuración para la GAL que he escrito para esta "mini-ULA". Está en lenguaje CUPL:
NOTA: en otro post del mismo hilo (que por desgracia no he podido recuperar) amplío el esquema para que además de teclado, se implemente MIC y altavoz. Debo tener el fichero con las ecuaciones en formato CUPL por ahí, así que en cuanto lo encuentre, actualizao al menos esa parte del post (el fichero de las ecuaciones).
Código: Seleccionar todo
Name lectura_teclado ;
PartNo 00 ;
Date 26/10/2010 ;
Revision 01 ;
Designer Miguel Angel Rodriguez Jodar ;
Company Dept. Arquitectura y Tecnologia de Computadores. Universidad de Sevilla ;
Assembly None ;
Location Sevilla ;
Device g16v8ma ;
/* *************** ENTRADAS *********************/
PIN 2 = IORQ;
PIN 3 = RD;
PIN 4 = A0;
PIN 5 = KB0;
PIN 6 = KB1;
PIN 7 = KB2;
PIN 8 = KB3;
PIN 9 = KB4;
/* *************** SALIDAS *********************/
PIN 15 = D0;
PIN 16 = D1;
PIN 17 = D2;
PIN 18 = D3;
PIN 19 = D4;
/* *************** ECUACIONES *********************/
D0=KB0;
D1=KB1;
D2=KB2;
D3=KB3;
D4=KB4;
ENABLE=!(IORQ # RD # A0);
D0.OE=ENABLE;
D1.OE=ENABLE;
D2.OE=ENABLE;
D3.OE=ENABLE;
D4.OE=ENABLE;