Ayuda con in y out

Sinclair QL, ZX81, +2, +3, 128K ...
Avatar de Usuario
Pachuquin
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 146
Registrado: 07 Ago 2013, 17:37
Sistema Favorito: Spectrum +2
primer_sistema: Dragon
consola_favorita: Nintendo DS/3DS
Primera consola: TV Games/Pong Clone
Gracias recibidas: 1 vez

Ayuda con in y out

Mensajepor Pachuquin » 28 Ago 2013, 19:37

Hola:

Estoy intentando cacharrear con mi "nuevo" Spectrum y aprovechar para aprender como funciona internamente y eso.

Estoy viendo esquemas de interfaces que ha hecho la gente y no consigo entender como se selecciona el puerto de entrada o salida en los comandos in y out.

Por ejemplo este montaje. Es una interfaz de 24 entradas/salidas con un 8255. Aquí hace referencia a los puertos 33, 35, 37 y 39, pero en el esquema sólo hace referencia a las direcciones A0, A1 y A2, con las que, según mis pobres conocimientos, se podrían seleccionar de la 0 a la 7, por lo que entiendo que las direcciones no se seleccionan como yo creo.

¿Conocéis alguna página donde expliquen el funcionamiento?


Gracias

Avatar de Usuario
mcleod_ideafix
Amiga 2500
Amiga 2500
Mensajes: 5316
Registrado: 06 Oct 2009, 04:12
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Vectrex
Primera consola: TV Games/Pong Clone
Ubicación: Jerez de la Frontera
Gracias dadas: 12 veces
Gracias recibidas: 54 veces
Contactar:

Re: Ayuda con in y out

Mensajepor mcleod_ideafix » 28 Ago 2013, 19:43

En la descripción dice:
This interface DOES NOT utilize the complete address decoding and PIO chip is accessed at every odd address

O sea, que para simplificar el diseño, esta interface es seleccionada usando cualquier dirección impar. Esta PIO usa cuatro puertos, seleccionados por los valores de A1 y A2. Sabiendo que A0 debe ser igual a 1 para que la inteface se seleccione, nos da como posibles puertos el 1,3,5 y 7 por ejemplo. En general, los puertos por los que accederás a esa PIO son (escritos en binario):

xxxxxxxx xxxxx001 (Puerto A)
xxxxxxxx xxxxx011 (Puerto B)
xxxxxxxx xxxxx101 (Puerto C)
xxxxxxxx xxxxx111 (Configuración)

Donde "x" es cualquier valor, 0 ó 1. Da igual.

El autor sugiere usar los puertos 33, 35, 37 y 39 sencillamente para que en el caso de que tengas algún otro periférico conectado a los buses, no se seleccione a la vez que esta PIO. El puerto 33 es
00000000 00100001

Es decir, el bit A5 a 1, para impedir que se seleccione el puerto de joystick Kempston. No es quizás la mejor elección de puertos, ya que con esta opción se puede seleccionar accidentalmente el puerto de la interfaz de joystick Fuller, y quien sabe qué otras cosas (DivIDE, etc). Yo hubiera optado por una en la que todos los bits no relevantes de la parte baja estuvieran a 1, es decir:

00000000 11111001 = 249 (puerto A)
00000000 11111011 = 251 (puerto B)
00000000 11111101 = 253 (puerto C)
00000000 11111111 = 255 (configuración)
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Pachuquin
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 146
Registrado: 07 Ago 2013, 17:37
Sistema Favorito: Spectrum +2
primer_sistema: Dragon
consola_favorita: Nintendo DS/3DS
Primera consola: TV Games/Pong Clone
Gracias recibidas: 1 vez

Re: Ayuda con in y out

Mensajepor Pachuquin » 28 Ago 2013, 19:53

Ah, vale, pero en el controlador dómestico de indescomp ¿no hacen lo mismo? ¿no? porque en las instrucciones hace referencia a la dirección 61441 y en el esquema están A5, A6 y A7 y encima pone que no se utiliza ¿?

Avatar de Usuario
mcleod_ideafix
Amiga 2500
Amiga 2500
Mensajes: 5316
Registrado: 06 Oct 2009, 04:12
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Vectrex
Primera consola: TV Games/Pong Clone
Ubicación: Jerez de la Frontera
Gracias dadas: 12 veces
Gracias recibidas: 54 veces
Contactar:

Re: Ayuda con in y out

Mensajepor mcleod_ideafix » 28 Ago 2013, 20:03

Pachuquin escribió:Ah, vale, pero en el controlador dómestico de indescomp ¿mo hacen lo mismo? ¿no? porque en las instrucciones hace referencia a la dirección 61441 y en el esquema están A5, A6 y A7 y encima pone que no se utiliza ¿?

No entiendo muy bien lo que aparece en ese esquema, porque si no se usan A5, A6 y A7, ¿cómo se decodifica la interface? No puede usarse simplemente con cualquier puerto, aunque el esquema parece sugerir precisamente eso, que cualquier operación de lecttura o escritura en cualquier puerto hace funcionar a esta interface, lo cual colisionaría con cualquier otra cosa que hubiera en el Spectrum, ULA incluida.
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Pachuquin
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 146
Registrado: 07 Ago 2013, 17:37
Sistema Favorito: Spectrum +2
primer_sistema: Dragon
consola_favorita: Nintendo DS/3DS
Primera consola: TV Games/Pong Clone
Gracias recibidas: 1 vez

Re: Ayuda con in y out

Mensajepor Pachuquin » 28 Ago 2013, 20:15

Luego si se quisiera que esa interfaz respondiera solamente al puerto 61441 habría que comprobar las direccions de la A0 a la A15 y comprobar que son 11110000 00000001 ¿no? ¿hay alguna forma de hacerlo más fácil?

Avatar de Usuario
mcleod_ideafix
Amiga 2500
Amiga 2500
Mensajes: 5316
Registrado: 06 Oct 2009, 04:12
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Vectrex
Primera consola: TV Games/Pong Clone
Ubicación: Jerez de la Frontera
Gracias dadas: 12 veces
Gracias recibidas: 54 veces
Contactar:

Re: Ayuda con in y out

Mensajepor mcleod_ideafix » 28 Ago 2013, 20:35

Pachuquin escribió:Luego si se quisiera que esa interfaz respondiera solamente al puerto 61441 habría que comprobar las direccions de la A0 a la A15 y comprobar que son 11110000 00000001 ¿no? ¿hay alguna forma de hacerlo más fácil?

Si quieres que la interfaz responda unicamente a esa dirección, sí, hay que comprobar todos los bits del bus de direcciones. ¿Forma de hacerlo fácil? Pues lo que hacen (hacían) muchos diseñadores de interfaces, y es realizar decodificación parcial. Es decir, sólo comprueban los valores de algunos de los bits del bus de direcciones y para los demás, se asume que tendrán el valor correcto. ¿El resultado? Pues que la interface está accesible en más de un puerto, y si no eliges bien qué bits decodificas y cuáles no, te puedes encontrar con que tu interface colisiona con otra que haya tenido a bien decodificar solamente los mismos bits que tú.

Por ejemplo, muchas interfaces Kempston decodifican A7,A6 y A5. Si estos tres bits valen 0, la inteface se selecciona. El puerto "oficial" de Kempston es el 31, que en binario sería 0001 1111 . O sea, todos los bits a 1 excepto A5,A6 y A7 (los bits de la parte alta del bus de direcciones no se suelen utilizar, aunque hay interfaces que sí lo hacen, como ULAplus y Spectranet, además del AY-3-8912 y los puertos de paginación del 128K)

Si tú decides ahorrar electrónica en tu interface y en lugar de decodificar por completo el puerto 61441 optas por decodificar unicamente A5,A6 y A7, te encontrarás que tu interface colisionará con un puerto Kempston. De hecho, y si te fijas bien, aunque decodificaras por completo tu interface, ésta colisionaría sin remedio con una interface Kempston que no decodifique el bus por completo, ya que el puerto 61441 tiene a 0 los bits A5,A6 y A7.

Es por eso por lo que en las recomendaciones de la especificación ZXI para diseñar nuevos periféricos para el Spectrum, se exige que el periférico haga decodificación total del bus de direcciones (las 16 líneas). La especificación recomienda un rango de puertos para tu periférico que se asegura de que no colisionan con ningún hardware existente.
http://www.zxshed.co.uk/sinclairfaq/ind ... I_standard

La forma más sencilla que se me ocurre de decodificar el bus completo para que tu interface se acceda con una y sólo una combinación de puerto válido, es usar algo como un par de comparadores 74HCT688. Cada uno de estos compara 8 bits. Las salidas de ambos pueden combinarse para dar una señal válida sólo cuando un valor de 16 bits en el bus de direcciones sea igual al esperado, o bien usar una GAL configurada como comparador que active una salida cuando los 16 bits del bus de direcciones sean iguales a un valor dado configurado dentro de la GAL.

Otra forma, un poco chusquera, pero válida, sería coger una EPROM de 64K (27512) y programarla de forma que todas sus posiciones de memoria tuvieran 0's menos una, que tendría 1's (o al revés, si quieres lógica invertida). La posición de memoria que tuviera el 1 en su bus de datos correspondería con aquella dirección que queremos detectar. Si la EPROM es rápida (menos de 100ns) puedes usarla en el Spectrum como decodificador de direcciones, conectando el bus de direcciones del procesador al bus de direcciones de la EEPROM. Cualquiera de los pines del bus de datos sería la línea de selección de tu periférico.
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Pachuquin
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 146
Registrado: 07 Ago 2013, 17:37
Sistema Favorito: Spectrum +2
primer_sistema: Dragon
consola_favorita: Nintendo DS/3DS
Primera consola: TV Games/Pong Clone
Gracias recibidas: 1 vez

Re: Ayuda con in y out

Mensajepor Pachuquin » 30 Ago 2013, 00:10

mcleod_ideafix escribió:La forma más sencilla que se me ocurre de decodificar el bus completo para que tu interface se acceda con una y sólo una combinación de puerto válido, es usar algo como un par de comparadores 74HCT688. Cada uno de estos compara 8 bits. Las salidas de ambos pueden combinarse para dar una señal válida sólo cuando un valor de 16 bits en el bus de direcciones sea igual al esperado, o bien usar una GAL configurada como comparador que active una salida cuando los 16 bits del bus de direcciones sean iguales a un valor dado configurado dentro de la GAL.


Ok, voy a intentarlo por ahí.

He estado mirando por ahí lo de las señales del bus de expansión y sólo he encontrado esto en microhobby.

¿Cuales sería los pasos para que la interfaz leyera y escribiera en el bus?

1º - Esperar a que la señal IORQ se active, lo que significa que se está intentando acceder a un dispositivo externo.
2º - Comprobar con el comparador que la dirección (A0-A15) es a la que responde nuestra interfaz.
3ª - Comprobar RD y WR, para ver si debemos leer o escribir en el bus de datos.
4º - Leer o escribir en el bus de datos.
5 - ¿Debemos activar alguna señal para indicar que ya hemos terminado el trabajo?

He estado buscando los componentes por Digikey para ver precios. ¿Que tienda online me recomendáis?

Avatar de Usuario
mcleod_ideafix
Amiga 2500
Amiga 2500
Mensajes: 5316
Registrado: 06 Oct 2009, 04:12
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Vectrex
Primera consola: TV Games/Pong Clone
Ubicación: Jerez de la Frontera
Gracias dadas: 12 veces
Gracias recibidas: 54 veces
Contactar:

Re: Ayuda con in y out

Mensajepor mcleod_ideafix » 30 Ago 2013, 00:19

Pachuquin escribió:1º - Esperar a que la señal IORQ se active, lo que significa que se está intentando acceder a un dispositivo externo.
2º - Comprobar con el comparador que la dirección (A0-A15) es a la que responde nuestra interfaz.
3ª - Comprobar RD y WR, para ver si debemos leer o escribir en el bus de datos.
4º - Leer o escribir en el bus de datos.


Exacto. Esto es lo que hay que hacer. Habitualmente las señales RD y WR van directamente al periférico. La señal CS del periférico se activa cuando IORQ está activa y además la dirección que aparece en el bus coincide con la dirección que se le ha asignado al periférico.
Otras veces es necesario incluir RD ó WR en la ecuación, ya que el periférico no tiene pines de RD y WR separados.

MIra un ejemplo de periférico en el número 36 de Microhobby: las páginas 23 y 24. En la 24, sobre todo, fíjate en la parte inferior del esquema, donde se decodifican las direcciones, IORQ, etc. Las direcciones de este periférico son 223 y 191 (según se dice en la página anterior)
http://www.microhobby.org/numero036.htm

Pachuquin escribió:5 - ¿Debemos activar alguna señal para indicar que ya hemos terminado el trabajo?

No. La interface con el procesador es síncrona. Se supone que el periférico debe ser capaz de responder en el tiempo estipulado, que son 3 ó 4 ciclos de reloj si mal no recuerdo. Si tu periférico es más lento que eso, debes poner la señal WAIT a 0 mientras tu periférico responde, y volverla a poner a 1 cuando termine. Habitualmente, esto no es necesario.

Pachuquin escribió:He estado buscando los componentes por Digikey para ver precios. ¿Que tienda online me recomendáis?

Yo compro en eBay, Digikey, Farnell, RS Amidata, y alguna vez en Jameco y Mouser, pero son las menos. Casi siempre uso GAL's o CPLD's así que no tengo que buscar integrados raros, sino que sólo necesito tener una buena remesa de este tipo de chips, y con ellos puedo "fabricar" cualquier otro, sea un comparador, un decodificador, un latch, etc,
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Pachuquin
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 146
Registrado: 07 Ago 2013, 17:37
Sistema Favorito: Spectrum +2
primer_sistema: Dragon
consola_favorita: Nintendo DS/3DS
Primera consola: TV Games/Pong Clone
Gracias recibidas: 1 vez

Re: Ayuda con in y out

Mensajepor Pachuquin » 30 Ago 2013, 01:05

Que modelo de Gal sueles usar mas a menudo y donde la pillas.

Avatar de Usuario
mcleod_ideafix
Amiga 2500
Amiga 2500
Mensajes: 5316
Registrado: 06 Oct 2009, 04:12
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Vectrex
Primera consola: TV Games/Pong Clone
Ubicación: Jerez de la Frontera
Gracias dadas: 12 veces
Gracias recibidas: 54 veces
Contactar:

Re: Ayuda con in y out

Mensajepor mcleod_ideafix » 30 Ago 2013, 01:29

Pachuquin escribió:Que modelo de Gal sueles usar mas a menudo y donde la pillas.

La GAL16V8 ó la GAV22V10, según lo que vaya a hacer. Las compro en eBay.

Para interfaces sencillitos, pero en los que una GAL ya no da de sí, uso una pequeña CPLD, la 9536. Con ella hice, por ejemplo, esta interface de joystick multiprotocolo:
http://foro.speccy.org/viewtopic.php?f=8&t=2271

-- Actualizado 30 Ago 2013, 02:57 --

Con una GAL pequeña, una 16V8, puedes hacer cosas curiosas, como ésta:

Código: Seleccionar todo

                         +5V
         ___________     ---
        |    \__/   |     |
        |1        20|-----+
WR -----|2    G   19|
IORQ ---|3    A   18|                 LED
A5 -----|4    L   17|    470 ohm    |\|
D0 -----|5    1   16|----/\/\/\/\---| |----+
        |6    6   15|               |/|    |
        |7    V   14|                      |
        |8    8   13|                     ---
        |9        12|                     GND
   +----|10       11|
   |    |___________|
   |     
  ---
  GND


Esto es, un pequeño circuito que decodifica cuándo se escribe en el puerto 223, y guarda en un latch el valor del bit D0 del bus de datos. Ese valor se queda guardado y sale por uno de los pines de la GAL, donde enciende o apaga un LED.

Para encender el led:
OUT 223,1

Para apagarlo:
OUT 223,0

La GAL tiene que ser configurada para que se "convierta" en el chip que queremos que sea. Es decir, describir cómo son las puertas lógicas que hay en su interior y cómo están conectadas. Este es el fichero que hay que compilar (convertir a un JED) para grabar con ella la GAL:

En las ecuaciones:
! = NOT
& = AND
# = OR

Código: Seleccionar todo

Name     LatchLED ;
PartNo   00 ;
Date     30/08/2013 ;
Revision 01 ;
Designer McLeod_IdeaFix ;
Company  ATC ;
Assembly None ;
Location  ;
Device   G16V8 ;

/* Pines de entrada */
PIN  2     = WR;
PIN  3     = IORQ;
PIN  4     = A5;
PIN  5     = D0;
/* Pines de salida */
PIN 16     = LED;
/*  Pines de E/S, internos al circuito */
PINNODE 17 = N_LED;

/* Decodificador escritura en puerto 223 */
deco_puerto = !(!IORQ & !A5 & !WR);

/* Latch D que guarda el valor de D0 */
ck_input = deco_puerto;
d_input = D0;
LED = !(N_LED # (ck_input & !d_input));
N_LED = !(LED # (ck_input & d_input));


Estas ecuaciones dan lugar a este circuito dentro de la GAL:
latchled.png
latchled.png (23.86 KiB) Visto 8665 veces

El decodificador es una puerta NAND de 3 entradas, cuya salida vale 1 sólo cuando se está escribiendo algo al puerto 223 (en binario este puerto es 11011111, es decir, todo a 1 excepto el bit A5 que es 0)
La salida es el latch enable de un biestable D muy sencillo hecho de forma clásica, usando dos puertas NOR cruzadas. La entrada D de este biestable viene directamente desde D0. Así, el valor que haya en D0 se almacenará en el biestable si y solo si hay una escritura en curso al puerto 223.

Las salidas Q y Q negada del biestable van a los pines 16 y 17 respectivamente, de la GAL. En el 16 es donde ponemos la resistencia y el LED para ver cómo se enciende y apaga cuando hacemos los OUT's.

Si no puedes acceder a una GAL en este momento, siempre te queda la opción de hacer el circuito con puertas lógicas de las habituales, como se muestra aquí.
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista


Volver a “Sinclair/Spectrum”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 9 invitados