Para quien tenga curiosidad morbosa y sea sea un poco masoca (como yo jejejeje), aquí os dejo la descripción anterior de como funciona el display ampliada con la parte del hardware.
No hay como seguir el circuito para empezar a despejar dudas.
La interpretación la he hecho basándome en el esquema publicado
aquí y el listado en ensamblador de la ROM que se puede encontrar
aquí.
La explicación viene dividida según las partes lógicas en las que podemos dividir el hardware.
Generador de NOPs
El circuito siguiente es el que se encarga de comprobar que estamos refrescando la pantalla.
La salida del circuito (patilla 6 de IC16) es igual a 0 cuando /HALT = 1, A15 = 1 y D6=0, osea siempre y cuando no estemos ejecutando un HALT (/HALT y D6=0) y estemos ejecutando algo en la segunda mitad de la memoria (A15=1), que como ya habíamos dicho solo ocurre cuando refrescamos la pantalla. Al comprobar que /HALT = 1 y D6 = 0 descartamos también el momento en el que ya hemos llegado a fin de línea.
La salida de este circuito va a parar al pin 9 de IC 17 (ver abajo) lo que hace que sólo tengamos un 0 a la salida de este “OR” (patilla 8 de IC 17) en el caso de que el circuito anterior sea 0 y /M1=0, es decir estemos pintando la pantalla y estemos en el ciclo de fetch.
Al tener un 0 en el pin 8 de IC 17 tendremos un 1 en el pin 2 de IC 15, lo que hará 0 todos los bits de datos (D0..D7) conectados al conjunto de NOPs de la figura de arriba.
Secuencia de visualización de video
IC5 es un circuito 74LS373 que consta de 8 latchs triestado. En este caso tenemos siempre a 0 la habilitación (patilla 1) por lo que los latch se utilizan como biestables.
Dicho circuito es el que se encarga de capturar cada código de carácter que es puesto es el bus de datos por la CPU cuando se está en la fase de refresco de pantalla. Estos datos acaban en el bus, ya que la CPU está ejecutando la zona correspondiente a DFile y por tanto poniendo el contenido de dicha memoria en el bus de datos, aunque como dijimos antes sólo se ejecutan NOPs ya que estos datos son sustituidos por ceros en la fase fetch.
En dicho circuito, capturamos únicamente los bits D0..D5 que son los 64 caracteres posibles y D7 que nos indica si hay que invertir el vídeo.
La patilla 11 (LE) que es activa en alta, es la que deja o no pasar los datos desde el bus de datos.
La patilla 11 se activa cuando alcanzamos la fase de RFSH, teniendo a uno la salida del circuito siguiente (patilla 4 de IC13):
La salida de IC5 es redirigida a los tres chips multiplexores IC6, IC7 e IC8 que seleccionan entre un acceso a ROM estándar o un acceso a la ROM de caracteres cuando estamos en la fase de refresco. La señal de selección (S) de dichos chips está conectada directamente a /RFSH, por lo que cuando /RFSH = 0 se seleccionan las entradas que llegan desde IC5, interpretando el código presente en el bus de datos como una dirección que apunta a la tabla de caracteres en ROM.
La correspondencia es como sigue:
D0 -> A3, D1 –> A4, D2 –> A5, D3 –> A6, D4 –> A7, D5 –> A8.
Estos 6 bits nos direccionan el carácter dentro de la tabla de caracteres.
El scanline del carácter a representar viene determinado por los tres bits inferiores, por lo que las 3 líneas inferiores se alimentan de un contador de 3 bits que reside en IC21 y que va contando cíclicamente al compás del sincronismo horizontal los 8 scanlines de cada carácter, y es reseteado cuando se dispara el sincronismo vertical.
Con lo anterior tenemos la dirección correspondiente al desplazamiento dentro de la tabla de caracteres del scanline a representar, pero nos falta añadir la dirección de tabla dentro de la ROM.
Los bits A9, A10 y A11 que nos faltan vienen directamente del bus de direcciones debido que estamos en el ciclo de refresco y en el programa de la ROM (antes de activar las interrupciones) hemos cargado convenientemente el registro I para que apunte a la tabla de caracteres en ROM:
Código: Seleccionar todo
LD A,$0E ; set the I register to $0E to tell
LD I,A ; the video hardware where to find
; the character set ($0E00).
Los datos de salida de la ROM, van a parar a la entrada de IC9 que se encarga de serializar los datos para enviarlos al display.
Por otro lado, el valor que entra de D7 en IC5, va a parar al circuito que controla la inversión del vídeo de los caracteres.
Este dato entra por la patilla 5 de IC11 acabando en un OR exclusivo con el dato serializado que viene por la patilla 4 de IC20, por lo que si D7 está a 1 el dato que llega se invertirá.
serialización de los datos de video.
La serialización la realiza IC9.
Se utiliza un reloj de 6,5MHz que le llega directamente del cristal. Este reloj entra por el pin 2.
La salida es normalmente el pin 7 (/Q) produciendo un video de caracteres blancos sobre fondo negro, pero puede modificarse utilizando el pin 9 (Q).
El pin 1 (S/L) habilita la serialización, permitiendo que fluyan los datos sólo cuando el pin 9 de IC5, que es un flip-flop, es igual a cero. Esto ocurre cuando estamos en la fase de refresco de pantalla indicado por el circuito de la página anterior (patilla 6 de IC16)
Los datos vienen desde el circuito que multiplexa el acceso a la ROM entre la CPU o el sistema de visualización. Este circuito está formado por los chips IC6, IC7 e IC8.
La visualización vista desde el lado del Z80.
Lo primero que llama la atención en el esquema es que /INT está conectado directamente con A6, eso significa que la línea correspondiente a la activación de las interrupciones enmascarables se activa simplemente accediendo a cualquier dirección cuyo bit 6 sea 0.
Leyendo el listado de la ROM del Z80, cuando echas un vistazo a la rutina de servicio de interrupciones, lo que te encuentras es que se carga en HL la dirección de la zona de pantalla+32Kb, inmediatamente después se activan las interrupciones con la instrucción “EI” y después hace un salto incondicional a dicha dirección, como si de un trozo de programa se tratara.
El hardware monitoriza la señal A15, por lo que todo acceso a una posición de memoria superior a 32Kb el sistema lo interpreta como que se está refrescando la pantalla y en lugar de meter en el bus de datos el contenido de la memoria, durante la fase de fetch, mete en dicho bus un 0, que es el código de la instrucción NOP o “No Operation”.
El programa continúa ejecutando NOPs hasta que se encuentra con una instrucción HALT en la memoria (en los zx80 y 81 se utiliza un HALT o $76 como fin de línea), momento en el cual el hardware deja pasar dicha instrucción y deja al procesador parado hasta que se active /INT. (La comprobación de si es una instrucción HALT la hace el hardware comprobando si el bit 6 del bus de datos está a 1, ya que su código es $76)
/INT se activa una vez ejecutados los 32 NOPs correspondientes a una línea de pantalla. Esto es así porque el registro R se incrementa cada vez que se ejecuta una instrucción, y este se carga adecuadamente, antes de hacer el salto a la zona de pantalla, con un valor tal que, después incrementarse 33 veces su bit 6 se hace 0.
El contenido del registro R, que es el encargado de direccionar el refresco de la memoria, va a parar al bus de direcciones al final del ciclo “fetch” o de búsqueda de instrucciones, por lo que A6=0 y se activa /INT, interrumpiendo la pausa en la que se encontraba el procesador (con HALT) y continuando con la ejecución del programa.
Lo que todavía no tengo nada claro es como se sincronizan los datos de vídeo con la frecuencia de 50Hz del televisor, ya que el serializador de datos funciona a 6.5MHz y los datos vienen de la CPU a 8 píxeles por cada 4 ciclos de reloj de 3.2MHz. Así por encima no me salen las cuentas, pero si algún experto en vídeo de por aquí me puede echar un cable se lo agradecería.
Y ya que estoy, y como me estoy animando
, igual os doy el tostón con el resto de los circuitos del ZX80, por lo que, continuará.........