fondo de menuRastersoft

Disco duro para Spectrum

Los discos duros IDE

Los discos duros IDE surgieron cuando Compaq necesitaba un modelo de pequeño tamaño para instalar en algunos modelos, en los cuales no había sitio en la placa madre para incluir una controladora. Para ello, pidió a la compañia Western Digital que realizase un disco duro con la controladora integrada en él, de modo que el Interface fuese lo más simple posible. Esta configuración permite una fácil adaptación: en efecto, basta con un simple puerto de E/S de 16 bits para realizar la conexión entre el disco duro y el ordenador.

Los discos duros IDE, al incluir la controladora, disponen de un buffer interno, y admiten comandos de alto nivel. Por ejemplo, para realizar una lectura, basta con indicarle la pista, cabeza y sector, darle la orden correspondiente, y una vez que el disco ha terminado, leer los datos de su buffer interno. Admite lecturas multisector, incluso pasando de una pista a otra.

A pesar de no ser una descripción completa, con los datos presentes es factible realizar la conexión de un disco duro IDE a cualquier ordenador. En mi caso concreto, he conectado uno a un Sinclair Spectrum, y estoy trabajando ahora en un S.O. y sistema de ficheros adecuado para trabajar con él.

Conexiones

El disco duro dispone de un conector de alimentación y otro de control. El primero, visto de frente, es como sigue:

                /------------\
                | o  o  o  o |
                --------------
                  1  2  3  4

        1: +5V
        2: GND
        3: GND
        4: +12V

Obviamente, esta vista es del conector situado en el disco duro, y visto por el lado opuesto a las soldaduras, esto es, por el lado en que se enchufa el conector proveniente de la fuente de alimentación (puedo parecer pedante, pero no quiero responsabilidades en caso de que alguien meta los 12 voltios por el pin de 5).

El segundo conector es de 40 pines, y las conexiones principales son:

        1: RESET
        3: D7           4: D8
        5: D6           6: D9
        7: D5           8: D10
        9: D4           10: D11
        11: D3          12: D12
        13: D2          14: D13
        15: D1          16: D14
        17: D0          18: D15
        19: GND
                        22: GND
        23: IOW         24: GND
        25: IOR         26: GND
        33: A1
        35: A0          36: A2
        37: CS1         38: CS2

El pin 1 suele venir indicado por una flecha grabada en el conector del disco duro.

El significado de las señales es el siguiente:

Registros del disco duro

Un disco duro IDE tiene una serie de registros internos, los cuales almacenan la información necesaria para hacer una operación. La forma de acceder a ellos consiste en seleccionar uno de ellos mediante las líneas A0, A1 y A2. En escritura, se debe poner el dato en los 8 bits inferiores del bus (salvo que se quiera escribir en el registro 0, que equivale a acceder al buffer de sectores, en cuyo caso se usan los 16 bits del bus) y activar con un nivel bajo la señal IOW, además de tener seleccionado el banco correspondiente, poniendo a estado alto o a bajo las señales CS1 y CS2, según corresponda. El primer banco es el que voy a describir aquí y es suficiente para trabajar con él. Desde el segundo se acceden a parámetros del disco duro, por lo que no es algo imprescindible. Para lectura, se debe poner a nivel bajo la señal IOR, apareciendo en los 8 bits inferiores (en los 16 si el acceso es al registro 0) el dato que contiene.

Cada uno de los 10 registros tiene una función concreta, y en algunos casos, son accesibles solo en lectura o solo en escritura. Esto permite que con solo 3 líneas de selección se pueda acceder a todos los registros. Su descripción en función del valor indicado en las líneas A0-A2 es la siguiente:

VALOR A0-A2   LECTURA               ESCRITURA
     0        Datos                 Datos
     1        Registro de errores   Escritura precompensada
     2        Contador de sectores  Contador de sectores
     3        Sector                Sector
     4        Cilindro (byte bajo)  Cilindro (byte bajo)
     5        Cilindro (byte alto)  Cilindro (byte alto)
     6        Unidad/cabeza         Unidad/cabeza
     7        Registro de estado    Registro de comandos

El REGISTRO DE DATOS permite acceder al buffer de memoria del disco, para leer o escribir los datos. En cada lectura o escritura se accede a 16 bits (es el único registro de este tamaño; el resto de los registros es de 8 bits), incrementandose automáticamente el puntero de memoria. De esta forma, para leer 512 bytes debemos hacer 256 lecturas al buffer.

El REGISTRO DE ERROR, de solo lectura, indica un posible error en el último comando introducido. Solo es válido cuando el bit de error del registro de estado está activo.

El REGISTRO DE ESCRITURA PRECOMPENSADA almacena el cilindro de comienzo para ésta, dividido por 4.

El CONTADOR DE SECTORES, como su nombre indica, lleva la cuenta de sectores a transferir en las operaciones multisector. Cuando son varios, el registro se va decrementando a la vez que se incrementa el registro de sector. Se debe especificar anter las características de la unidad con el comando SET PARAMETERS antes de una transferencia multisector. Este registro debe cargarse antes de cualquier comando relacionado con datos. Un valor 0 indica 256 sectores.

El REGISTRO DE SECTOR indica el número de sector a leer o escribir, o bien el sector inicial en las operaciones multisector.

El REGISTRO DE CILINDRO, dividido en dos mitades, contiene el número de cilindro para cualquier comando, o bien el cilindro inicial para una operación multisector.

El REGISTRO DE UNIDAD/CABEZA debe tener los bits 7 y 5 a uno, y el 6 a cero. El bit 4 indica la unidad: 0 para el disco duro maestro y 1 para el disco duro esclavo. Los bits 0 a 3 indican el número de cabezal.

El REGISTRO DE ESTADO se actualiza tras cada comando. Se debe comprobar este registro para conocer el resultado de la operación. Solo será válido si el bit 7 (busy) está inactivo. Su significado por bits es:

El REGISTRO DE COMANDOS acepta un total de 8. Primero se deben cargar los registros necesarios para su ejecución, y luego éste, iniciandose entonces la operación. Un comando no válido da un error de COMANDO ABORTADO. Los comandos son:

    RESTORE         0   0   0   1   0   0   0   0
    SEEK            0   1   1   1   0   0   0   0
    READ SECTOR     0   0   1   0   0   0   0   T
    WRITE SECTOR    0   0   1   1   0   0   0   T
    FORMAT TRACK    0   1   0   1   0   0   0   0
    READ VERIFY     0   1   0   0   0   0   0   T
    DIAGNOSE        1   0   0   1   0   0   0   0
    SET PARAM       1   0   0   1   0   0   0   1

T indica el modo de reintentos: a 0 los habilita (se reintenta hasta 16 veces en caso de error), mientras que 1 los deshabilita (hasta 2 vueltas de disco).

Los comandos RESTORE y SEEK, en muchos casos, no son ejecutados por el disco duro. Esto no es problemático, pues las ordenes de leer y escribir sectores sitúan automáticamente los cabezales. Lo mismo ocurre con FORMAT TRACK, orden que es ignorada por la gran mayoría de discos duros IDE, pues un formateo a bajo nivel puede ser peligroso (suele bajar el rendimiento, y eso si no se carga el propio disco).

READ SECTOR: situa los cabezales en la posición indicada por los registros SECTOR, CILINDRO y PISTA, y lee un grupo de sectores (1-256) en el buffer interno, dejandolos listos para ser leidos.

WRITE SECTOR: situa los cabezales en la posición indicada por los registros SECTOR, CILINDRO y PISTA, y escribe en dicha posición los datos del buffer interno en disco. Admite escrituras multi-sector (1-256 sectores seguidos).

READ-VERIFY: similar a READ SECTOR, pero los datos no se envian al ordenador, sino que solo se comprueba que estén correctos. Permite comprobar la fiabilidad de los datos almacenados.

DIAGNOSE: el controlador realiza un AUTOTEST y devuelve el resultado en el REGISTRO DE ERROR. Este test se realiza automáticamente al encender el disco duro.

SET PARAM: establece los parámetros de la unidad: número de cabezales y sectores por pista. Estos datos deben ir en los registros SECTOR, CILINDRO y DRIVE/HEAD.

Ejemplo de programación

Para leer un sector, procederíamos a realizar los siguientes pasos:

Para escribir un sector, seguiremos los mismos pasos, pero enviando una orden de escritura y luego los 512 bytes a almacenar al buffer del disco duro, mediante 256 escrituras al registro de datos. A continuación comprobaremos los bits de estado para comprobar que no hubiese ningún error.

Sugerencias de conexión

Si alguien se decide a conectar un disco duro IDE a su queridísimo ordenador de 8 bits (Spectrum, CPC, MSX, etc), conviene que recuerde que necesita hacer una adaptación para poder leer y escribir grupos de 16 bits. Una primera solución consiste en desperdiciar la mitad de la capacidad del disco duro, y conectar solo la parte baja del bus (recordemos que el acceso a los registros de estado, sector, etc. es a 8 bits). Es la solución más simple, y si el disco duro no costó mucho (en mi caso me salió por 500 pts :-) puede ser adecuado. Sin embargo, no es la opción ideal, pues significa tirar 256 bytes de los 512 que forma cada sector. Una solución más adecuada consiste en añadir dos grupos de 8 biestables con salida triestado, capaces de almacenar los datos correspondientes a las 8 líneas superiores, tanto para lectura como para escritura, accediendo el ordenador a ellos a traves de un puerto diferente. Sin embargo, no es tan fácil como puede parecer: la lectura o salida de datos en el grupo de biestables 1 (que supondremos que es el usado para que el ordenador envíe al disco duro los 16 bits superiores) tiene que estar conectada a la señal de escritura del puerto usado para acceder a los 8 bits inferiores, de modo que cuando enviemos éstos, se habilitará la salida de éste biestable, y también serán entregados los 8 bits superiores (los biestables no pueden entregar el dato constantemente pues en una lectura habría un conflicto de tensiones entre esa salida y el dato que intenta enviar el propio disco duro). Por supuesto, esta señal debe ir conectada también a la señal IOW del disco duro. Respecto a la escritura o entrada de datos en el grupo de biestables 2, debe estar conectada a la señal de lectura del puerto usado para acceder a los 8 bits inferiores, de modo que cuando leamos estos, en dicho registro se almacenarán los 8 superiores, en espera de que los leamos a continuación.

De aquí se deduce que para escribir un dato de 16 bits en el buffer del disco duro, primero debemos enviar los 8 bits superiores, que serán almacenados en los biestables 1, y cuando enviemos los 8 bits inferiores, estos biestables activarán su salida también, de modo que entregaremos a la vez los 16 bits que precisa. Para la lectura, el proceso es el inverso: primero leemos los 8 bits inferiores, con lo que el disco duro nos da 16; pero como la señal de lectura va conectada a la señal de escritura de los biestables 2, éstos retienen los 8 bits superiores, los cuales podremos leer a continuación accediendo al segundo puerto.

Los puertos a escoger en cada caso dependen del ordenador, e incluso de los gustos de cada uno. En el Spectrum, que es mi caso, es muy común asignar una línea del bus de direcciones a cada periférico. Por ejemplo, la línea A0, al ponerse a nivel bajo, activa el puerto de la ULA; la línea A1 se usa para la impresora ZX; la A2 para la memoria paginada en los modelos de 128K, y así sucesivamente. Por esto no se deben hacer accesos a puertos poniendo a nivel bajo dos líneas, pues en ese caso se accedería a dos periféricos a la vez, con el consiguiente conflicto de voltajes en el bus de datos.

Para no desperdiciar los pocos puertos que quedan (se usan solo los 8 bits inferiores, y el A5 está reservado para el JoyStick) preferí usar la línea A3 para todo el conjunto, y utilizar luego otras líneas de las 8 superiores para acceder a cada puerto. Así, si pongo a nivel bajo A3 y A14, accedo al byte bajo del disco duro, mientras que con A3 y A15 accedo al byte alto (no debo poner A3, A14 y A15 a nivel bajo a la vez pues accedería a ambos puertos a la vez y podría haber un conflicto en las tensiones entregadas por los integrados, haciendo que se resetease el ordenador).

Para seleccionar el registro en el que leer o escribir (o sea, las líneas A0-A2 del disco duro), uso también líneas del bus de direcciones del microprocesador, en concreto A8, A9 y A10, que van directas a A0, A1 y A2, respectivamente, del disco duro. De este modo, para escribir en un registro, debo indicar en esos tres bits su número, y poner A3 y A14 a nivel bajo.

Otro detalle importante consiste en añadir un ligero retardo en la línea IOR. En efecto, si cuando termina el acceso de lectura, se 'cierran' las líneas triestado del disco duro a la vez que las entradas del biestable 2, puede ocurrir que, por retardos internos de los integrados, la circuitería del disco duro se cierre antes que las entradas del biestable, apareciendo falsos datos. Si se coloca un ligero retardo hecho con una o dos puertas seguidas, las entradas del biestable se cerrarán un poquito antes que las del disco duro, conservando así el dato correcto. En mi caso, he preferido biestables activados por niveles en vez de por flancos.

¡La línea de reset! Yo la he conectado al pin RESET del propio Z80 (en el Spectrum, esta línea está disponible en el bus trasero), de modo que al resetear el ordenador también inicializo el disco duro. Si no dispones de esa señal en tu bus, deberas añadir un pulsador a masa y una resistencia de 4K7 entre ese pin y +5V. Si incluyes un condensador de unos 1000uF entre ese pin y masa, conseguiras un auto-reset en el momento de encenderlo.

Por último, queda otro problema, aparentemente trivial, pero que no lo es tanto: la alimentación. Si bien los discos duros actuales consumen bastante poco, dudo que nadie compre uno de 1.2 GB para meter en su Spectrum :-) sino que seguramente la elección general será alguno de segunda mano de poca capacidad (en mi caso, conseguí una excelente tanqueta -o sea, del tamaño de los antiguos MFM/RLL- por un precio regalado). Estos discos duros antiguos suelen tener un consumo algo apreciable, que puede llegar a los 400-600 mA en cada una de las alimentaciones (o sea, que el total andará cerca del amperio). Esto descarta, en principio, el uso de la propia fuente del ordenador, incluso para la parte de 5 voltios. En algunos casos concretos (Spectrum +2A y +3, y CPC 6128) en que la fuente está sobredimensionada para soportar una unidad de disquetes de un modelo muy antiguo (y por tanto, de alto consumo :-) es posible (y recalco, SOLO POSIBLE) que soporte el añadido del HD, pero mejor que probarlo es hechar un vistazo a las especificaciones de la fuente (vienen debajo de ella y en el manual) y al consumo del ordenador, y luego comprobar con una fuente de PC cuanto chupa nuestra unidad fija. Así sabremos si podemos conectarla o no.

En caso de hacer una fuente propia, recordad que tiene que ser estabilizada, así que tendreis que añadir los inevitables 7805 y 7812, bien sujetos a una aleta de refrigeración (una lámina de aluminio con una superfície adecuada suele ser suficiente). No olvideis que deben ser alimentados con, al menos, 3 voltios más de los que deben ofrecer a su salida, así que escoged bien el transformador. Un último consejo: procurad que tenga dos salidas; una de 9 vóltios y otra de 16, en vez de conectar ambos reguladores a un trafo de 16 voltios. Así evitareis que el 7805 se recaliente.

Lo siguiente es un esquema muy simplificado del interface IDE para Spectrum. Los 74LS244 son puertas buffer triestado, cuya señal de activación es STROBE. Los 74LS374 son biestables con salida triestado. La señal MMO almacena el dato de IN en los biestables, y la señal SAL activa las salidas triestado. En este esquema uso la señal A3 para acceder a la parte baja del bus del disco duro, y la A4 para la parte alta, simplemente para no liar mucho el dibujo. Sin embargo, no es nada dificil completarlo para que funcione como lo he hecho yo, mediante puertos de la mitad superior del bus.

La lista de conexiones situada abajo a la derecha son conexiones directas desde pines del bus de expansion del Spectrum al conector de disco duro.

Esquema eléctrico de la interfaz

P.D. No me hago responsable de ninguna avería causada por un circuito basado en este artículo. Si te equivocas al montar algo, será exclusivamente culpa tuya.

Licencia de Creative Commons
Esta obra está bajo una licencia de Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional.