Reproductor de ficheros PZX dentro del propio clon

Responder
Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

Reproductor de ficheros PZX dentro del propio clon

Mensaje por mcleod_ideafix » 28 Sep 2015, 03:36

... o cómo cargar cualquier programa, aunque esté en un TZX y use una carga turbo, sin necesidad de móviles, cintas ni cables a la salida de audio del PC ;)
Luego comento más cositas, pero de momento, os haceis una idea de lo que he estado haciendo ayer, con este pequeño video:

phpBB [media]
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

Re: Reproductor de ficheros PZX dentro del propio clon

Mensaje por mcleod_ideafix » 28 Sep 2015, 03:37

Este reproductor es sólamente un ejemplo de lo que se puede hacer con esta plaquita de memoria añadida. La memoria es de 10ns, muy rápida, aunque para esta aplicación no se necesita tanta velocidad, pero sí una de unos 35ns como mucho, ya que todo el engine va a 28MHz. Va a esa velocidad porque para procesar los distintos bloques, primero hay que leerlos de RAM, y esto se hace bajo demanda. Al usar una única máquina de estados, el comportamiento es secuencial: o se lee memoria, o se reproduce sonido, pero no ambas cosas a la vez. La FPGA permitiría hacer ambas cosas a la vez sin ningún problema, pero esto complicaría el diseño de la máquina de estados y para algo que he escrito en un fin de semana, y que es un campo relativamente nuevo, no me he atrevido a nada más complejo. Decía pues: como hay que leer los datos de la RAM para preparar el siguiente pulso o dato, es necesario tardar lo menos posible en hacerlo para que la reproducción no se resiente (no aparezcan "gaps" en la señal de audio). Con la implementación actual, el peor caso se da cuando hay que leer un bloque DATA que tenga llenos los dos vectores de pulsos para 0 y 1: esto son dos vectores, de 32 elementos de 16 bits cada uno, y la memoria me da 8 bits en cada ciclo de reloj de 28MHz, así que consumo 2*32*2 = 128 ciclos de reloj de 28MHz que equivalen a 128/8=16 ciclos de reloj de CPU: este sería el error más grande que se cometería al generar los pulsos. 16 ciclos está aún bastante por debajo de la tolerancia que tienen los cargadores, incluso los más exigentes. Lo habitual es que los bloques DATA contengan vectores con dos elementos cada uno, no 32, así que el error cometido viene a ser de 2*2*2=8 ciclos de reloj de 28MHz, o 1 ciclo de reloj de CPU.

En la huella actual de memoria no he encontrado ninguna que sea de más de 512KB. Cambiar la huella para ponr otra memoria implica hacer otra tirada de placas de prototipo, y retrasar aún más el lanzamiento por crowfunding. Dado que el reproductor no es un elemento indispensable para que el ZX-Uno funcione, yo optaría por dejar el ZX-Uno como está. Además, ya serían 3 maestros del bus atacando a la misma memoria: la ULA, la CPU y el reproductor, por lo que una memoria de 45ns (que ya resulta lenta con la configuración actual) no daría de sí.

La otra cosa es que el reproductor ocupa del orden del 15% de los recursos de la FPGA. El core que lleva el reproductor ocupa el 74% de la FPGA, por lo que ponerlo "de serie" podría afecta a otras características que sí interesa que estén de serie, como el scandoubler.

De todas formas, esto que os he enseñado es sólo una primera versión, hecha un poco aprisa y corriendo en un solo día. La máquina de estados que implementa el reproductor es un tanto inestable y querría refactorizarla, ahora que tengo escritas las utilidades para poder cargar ficheros PZX desde ESXDOS y que sé que funcionan. No hay ruta de datos y controlador, sólo una máquina con unos 36 estados, obligando al sintetizador a inferir la ruta de datos él solo, cuando si la hiciera desde el principio podría ahorrarme muchos registos, y probablemente "tunearla" para que funcione con memorias más lentas.

Por ejemplo, faltan algunas cosas como algún sistema para avanzar y rebobinar. No es nada sencillo, porque ello implicaría tener un listado de índices, al estilo de la tabla de índices que hay al final de los ficheros AVI, para buscar los puntos a los que se puede rebobinar y/o avanzar (al no ser un WAV no puedes sencillamente añadir o quitarle una cantidad fija al puntero de direcciones de la SRAM para cambiar de posición), y por supuesto añadir la lógica correspondiente para realizar esta operación. Con la arquitectura actual, probablemente la máquina de estados "salte por los aires", así que lo tendré en cuenta para cuando la refactorice y diseñe su ruta de datos.

Este experimento también me vale como campo de pruebas para algo más: la posibilidad de extraer el reproductor e implementarlo como un dispositivo independiente, junto a un engine DivMMC, en un periférico para Spectrum "original". Sería probablemente la primera versión de DivMMC que sí sería capaz de leer ficheros de cinta con cargas turbo :)

Por otra parte, el addon de memoria lo he hecho no sólamente para esta aplicación (que de hecho fue algo que se me ocurrió después de haberla diseñado y mandado a fabricar la placa) sino para otra cosita, bastante menos útil quizás que el reproductor, pero que me hace ilusión: ponerle al ZX-Uno algo parecido al chip 8364 Paula, del Commodore Amiga: o sea, 4 canales de audio digitalizado por DMA, y escribir un comando en ESXDOS capaz de leer ficheros MOD y reproducirlos. No hay ningún software existente que pudiera hacer uso de esta aplicación, y con toda probabilidad nunca lo habrá, pero a mi me hace ilusión poder hacerlo :D (envidia sana que le tengo al Amiga)

La última razón por la que he hecho esto es, para quien haya leido el resumen del trabajo de Fin de Master que puse a vuestra disposición en otro hilo, como entrenamiento para el diseño de máquinas de estado más complejas, cosa que me hará falta en la tesis.
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Responder