Interfaz de Arduino con el puerto de cinta de C64

8

Actualización : una implementación práctica de esto se realiza en el proyecto Tapuino realizado por Peter Edwards. Compruébalo, todo es de código abierto: https://github.com/sweetlilmre/tapuino


Estoy trabajando en un proyecto en el que estoy usando mi Arduino para transmitir archivos de datos de cinta TAP desde mi PC al C64. El lado del software del proyecto va bien, sin embargo, todavía soy nuevo en electrónica y no me gusta freír mi Commodore. Así que necesito ayuda de interfaz de hardware en realidad.

Las cintas C64 utilizan la modulación PWM para almacenar el programa en cinta de cassette y al leer los datos, un disparador opamp + schmitt convierte la señal de audio en ondas cuadradas. Cada transición alto-bajo provoca una interrupción en la máquina y la distancia entre dos interrupciones (que es la longitud del pulso) representa una parte atómica de la corriente.

El pinout del puerto del cassette se ve así (la parte superior e inferior tiene los mismos pines dos veces):

Puerto de cinta de C64

A-1 , GND, tierra

B-2 , + 5V, 5 voltios DC

C-3 , MOTOR, Control del motor, aprox. Fuente de alimentación de 6 voltios del motor

D-4 , LEER, Entrada de datos, leer datos del datasette

E-5 , ESCRIBIR, Salida de datos, escribir datos en el datasette

F-6 , SENSE, Detection, si se presiona una de las teclas PLAY, RECORD, F.FWD o REW

Mi idea actual es la siguiente:

Basado en el Libro azul de interfaz C64 (a partir de la página 29), la máquina usa el nivel TTL en el puerto READ y WRITE, así que supongo que puedo conectar directamente un pin PWM del Arduino al pin READ.

También necesito interactuar con el pin SENSE. Creo que también puedo conectarlo directamente a uno de los PIN digitales y escribir BAJO digital allí cuando necesito indicar el estado del botón presionado. ¿Es eso correcto?

Más tarde, deseo detectar la presencia de una señal de + 6V en el pin MOTOR. Algunos cargadores detienen el conjunto de datos en el medio del proceso de carga, así que tengo que detectar eso también para emular la cinta correctamente. ¿Debo usar algún tipo de resistencia para limitar la corriente allí o puedo conectarla directamente también? Tal vez debería usar un relé allí?

NagyI
fuente
La señal PWM del Arduino va al pin WRITE (no READ).
Telaclavo
Me gusta emular el conjunto de datos con Arduino, por lo que debería interactuar con el pin READ porque es donde el C64 acepta la entrada.
NagyI
Por lo que entiendo el formato de los datos, no repites los pulsos como una señal PWM clásica, pero es la combinación de pulsos largos, medios y largos los que transportan los datos. ¿Puede el Arduino enviar señales PWM como esa?
Johncl

Respuestas:

4

Según el documento que proporcionó, el puerto del datasette está buscando una señal digital pura con un ciclo de trabajo variable (0.75 para H, 0.25 para L).

Mientras el pin Arduino pueda conducir suficiente corriente (debería poder) y esté operando a 5V, una conexión directa funcionará. Es posible que desee investigar utilizando un búfer TTL entre el Arduino y el C64 (el búfer se alimentaría del suministro de +5 del puerto del datasette, y la conexión a tierra sería común tanto para el C64 como para el Arduino).

En cuanto al SENSE, sería más fácil usar una salida digital para controlar un MOSFET de pequeña señal (como un 2N7002): una lógica alta enciende el MOSFET, que tira del pin SENSE (conectado al drenaje) a tierra (conectado a la fuente) sin que el Arduino tenga que hundir ninguna corriente en absoluto.

El pin MOTOR también podría usarse para conducir una puerta MOSFET. El drenaje se elevaría hasta el voltaje de suministro de Arduino con un pullup débil (10k más o menos), la fuente conectada a tierra. El drenaje también iría a un pin lógico digital. Cuando MOTOR es alto, la entrada lógica es baja y viceversa, y el Arduino ve una señal lógica limpia.

Por ejemplo...

Arduino a C64 V1

Tenga en cuenta el uso de dos puertas NAND como una especie de búfer. (¿Puedes decir que solía buscar piezas?)

TTL es bastante robusto. No creo que haya muchas posibilidades de dañar nada.

Adam Lawrence
fuente
Wow, buenos esquemas. Creo que primero intentaré conectar el pin de salida PWM de Arduino directamente a D-4 porque también usa 5V. ¡Gracias de todas formas! :)
NagyI
@NagyI Debería funcionar.
Adam Lawrence
Oh mi, no he aceptado esta respuesta? Me avergüenza. De todos modos, acabo de ordenar el conector de borde de cinta para probar esto y mi estación de soldadura llega la próxima semana. Así que espero poder probar esto pronto :)
NagyI
Como no pude obtener un 2N7002, mi colega me sugirió el BS170. La señalización de sentido funciona perfectamente. Sin embargo, la detección del motor está rota. Arduino siempre lee la lógica baja. No importa si pongo Gate en Low o High, Arduino siempre lee la lógica low. ¿Es este el problema del BS170 o algo diferente? Lo he intentado con otro BS170 pero el problema persiste. Me parece que BS170 solo puede cambiar GND pero no voltaje.
NagyI
2

Suena como un proyecto interesante. Recuerdo que el hardware del VIC-20 alimentaba pulsos del Datasette a un circuito de detección de bordes (no recuerdo si detectó bordes ascendentes o descendentes); las rutinas de carga de cinta C64 eran compatibles con las del VIC-20, por lo que no creo que el cargador estándar pudiera haber usado ningún truco que el VIC-20 no admitiría, aunque los cargadores personalizados podrían hacerlo. Nunca jugué con cosas en el día lo suficiente como para determinar si el Datasette en sí mismo convirtió los bordes ascendentes y descendentes en pulsos (por ejemplo, alimentando una señal retrasada y no retrasada en una puerta XOR). Se me ocurrió una rutina para convertir datos en anchos de pulso, pero nunca descubrí cómo usar el detector de bordes.

Con respecto a la transmisión de datos desde la PC al C64, si no desea utilizar una tarjeta de sonido (algunas tarjetas de sonido tienen procesamiento de imagen estéreo y pueden causar estragos en la fase de audio saliente) hay dos enfoques. podría sugerir: (1) enviar datos de intervalos de pulso desde la PC al Arduino, y simplemente hacer que el tiempo de Arduino sea individual. Quizás codifique el formato de datos con dos pulsos por byte, usando algo como la siguiente codificación:

Font>1100: genera un máximo de 20us seguido de un mínimo de 24-60us (en múltiplos de 3us)
1101 - Salida 40us baja
1110 - Salida 80us bajo
1111 - Los valores de bytes de $ FF serán ignorados
          - Otros byes con un nybble igual a 1111 podrían usarse para simular el
             tape los botones del motor o indique una indicación de "está bien pausar aquí".

No creo que ningún esquema de carga intente cronometrar pulsos con una precisión superior a 3us, y este esquema permitiría enviar datos a través de un UART a 115200. La PC debería agregar bytes de relleno 0xFF para que la velocidad a la que se envían los datos el Arduino coincidirá razonablemente con la velocidad a la que el Arduino lo está registrando. Debido a que cada nybble tardará entre 44 y 80 microsegundos en procesarse, el Arduino solo tendría que sondear su UART entre nybbles y podría desactivar las interrupciones cerca del final de cada pulso. Si la PC almacena sus datos de manera razonablemente efectiva, uno podría (1) hacer que la PC intente enviar datos un poco más rápido de lo que el Arduino los generaría, y usar el apretón de manos de hardware o software para ralentizarlos, o (2) tener el Arduino afeite un microsegundo de cada pulso cuando su búfer esté casi lleno, o agregue un microsegundo a cada pulso cuando su búfer esté casi vacío. Para evitar que se produzcan fallas en el audio debido a problemas momentáneos con la PC, uno podría hacer que el Arduino suspenda la emisión en un byte "está bien pausar aquí" si su búfer no está casi lleno.

Super gato
fuente
Gracias por las ideas. En realidad, estoy transmitiendo los datos del archivo TAP directamente al Arduino. Especifica cada pulso con un byte. (ver: c64tapes.org/dokuwiki/doku.php?id=analyzing_loaders ) Al superar los problemas técnicos de la transferencia de datos, estoy usando un búfer circular de un kB en el Arduino que se está completando en el bucle principal. La función de interrupción adjunta al evento de coincidencia del generador PWM consume los datos. Esto se llama dos veces por pulso. Ahí es donde estoy cambiando el nivel del PIN y en la transición alto-bajo estoy escribiendo el nuevo valor de registro de coincidencia de acuerdo con el siguiente byte.
NagyI