ZX-UNO: reproductor de ficheros PZX dentro del propio clon

Sinclair QL, ZX81, +2, +3, 128K ...
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:

ZX-UNO: reproductor de ficheros PZX dentro del propio clon

Mensajepor mcleod_ideafix » 21 Jun 2015, 06:47

... 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:

Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Quest
Atari 1040 STf
Atari 1040 STf
Mensajes: 900
Registrado: 18 Jul 2013, 22:20
Sistema Favorito: Commodore Amiga
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo SNES
Primera consola: Nintendo NES/Clónica
Gracias dadas: 9 veces
Gracias recibidas: 16 veces

Re: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor Quest » 21 Jun 2015, 08:36

Wow, que bueno :) reproductor pzx por hardware...

No conocia la demo en streaming, me he quedado "anonadao"

=D>

-- Actualizado 21 Jun 2015, 07:39 --

Por cierto, una pregumta q me viene a la mente... En una proxima revision de la placa del ZXUNO seria posible que en el hueco de la actual SRAM se pudiera poner opcionalmente, a eleccion del consumidor una SRAM de 1024k o de 512k, y en el primer caso, usar la segunda mitad de esa memoria para el reproductor pzx (modificandolo, supongo) o sera obligatorio usar plaquita externa?

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2013
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 8 veces

Re: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor antoniovillena » 21 Jun 2015, 12:26

Quest escribió:Por cierto, una pregumta q me viene a la mente... En una proxima revision de la placa del ZXUNO seria posible que en el hueco de la actual SRAM se pudiera poner opcionalmente, a eleccion del consumidor una SRAM de 1024k o de 512k, y en el primer caso, usar la segunda mitad de esa memoria para el reproductor pzx (modificandolo, supongo) o sera obligatorio usar plaquita externa?


La próxima revisión será la definitiva, que vendrá montada. No tiene sentido soldar una memoria de 512K en una huella de 1024K, porque el número de usuarios que se planteen desoldar una memoria para soldar otra (a mano) sería residual. Lo que no descarto es poner 1024K de serie, siempre y cuando encontremos una memoria igual de rápida (45ns) y no mucho más cara que la actual de 512K.

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: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor mcleod_ideafix » 21 Jun 2015, 13:29

Quest escribió:Por cierto, una pregumta q me viene a la mente... En una proxima revision de la placa del ZXUNO seria posible que en el hueco de la actual SRAM se pudiera poner opcionalmente, a eleccion del consumidor una SRAM de 1024k o de 512k, y en el primer caso, usar la segunda mitad de esa memoria para el reproductor pzx (modificandolo, supongo) o sera obligatorio usar plaquita externa?

A lo que ha contado Antonio, añado:

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.
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Quest
Atari 1040 STf
Atari 1040 STf
Mensajes: 900
Registrado: 18 Jul 2013, 22:20
Sistema Favorito: Commodore Amiga
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo SNES
Primera consola: Nintendo NES/Clónica
Gracias dadas: 9 veces
Gracias recibidas: 16 veces

Re: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor Quest » 21 Jun 2015, 14:40

Muchas gracias por todas las explicaciones a ambos. Queda 100% claro cristalino :D

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2013
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 8 veces

Re: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor antoniovillena » 21 Jun 2015, 14:46

Creo que la solución pasaría por "softwarizarla", o lo que es lo mismo, hacer que algunas partes de la implementación pasen de la FPGA al micro Z80 sintetizado. El problema es que serían muchos pasos y un desarrollo largo, pero como beneficio extra podrían leerse también archivos .TZX.

El software podría meterse en BRAM, prácticamente tenemos 16K libres en la zona de bootloader cuando BOOTM=1. La conmutación entre procesos no sería estándar. Habría que inventarse un modo NMI especial y añadirlo al core Z80. La idea es usar mucha menos memoria SRAM como buffer (16K ó 32K) para no tener que usar un chip externo y hacer que cuando el subsistema de la FPGA (que produce la onda) haya leído dicho buffer, invoque esta interrupción especial y salte directamente a BOOTM=1. Por ejemplo a la dirección $100 para dejar suficiente hueco al bootloader (que actualmente acaba en $38). Esta rutina accedería al archivo de la SD para recargar el buffer desde el archivo PZX (o TZX) y cuando termine, salir con BOOTM=0 y el PC donde estaba.

Esto produciría un pequeño corte en el sonido de carga, pero no afectaría a la carga en sí. Y no sería nada fácil, porque habría que implementar varias capas (acceso SD, sistema de ficheros FAT) o bien utilizar la API del DivMMC.

-- Actualizado 21 Jun 2015, 13:57 --

Ahora que caigo sería más óptimo usar la dirección $0066, ya que la única diferencia entre una NMI y esta interrupción especial es que entra con BOOTM=1 y sale con BOOTM=0. Hay 2 formas:
1. Implementar un nuevo FLAG de interrupción, IFF3, que indique que estamos en este modo de interrupción especial, para retornar con el valor original que tenía BOOTM antes de la interrupción.
2. O bien no implementar dicho FLAG y forzar BOOTM=0 en la instrucción RETN, a fin de cuentas no usamos NMI en la BIOS.

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: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor mcleod_ideafix » 21 Jun 2015, 15:29

antoniovillena escribió:Creo que la solución pasaría por "softwarizarla", o lo que es lo mismo, hacer que algunas partes de la implementación pasen de la FPGA al micro Z80 sintetizado.

El Z80 es sencillamente demasiado lento. Tú lo que estás sugiriendo es una multitarea entre el código "de usuario" que corre el Z80 y el código que implementa el reproductor de PZX, pero a nivel de instrucción: una instrucción de código de usuario, una del reproductor PZX, y así. Hay formas de hacerlo, que implican modificar extensivamente el core del T80, y aunque funcionara, el resultado no sería el mismo que el de una carga a velocidad nominal, como tenemos aquí ahora, sino que tendrías una carga turbo a cámara lenta. La demo del cargador musical, por ejemplo, te la cargas, o la de "Tape Loading Era". Sinceramente, no veo la solución "softwarizada".
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2013
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 8 veces

Re: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor antoniovillena » 21 Jun 2015, 16:24

No. Creo que me he explicado mal. Sería modificar lo que tienes ahora con el fin de utilizar menos recursos de RAM. La parte del Z80 no sería realmente multitarea, por lo que cada vez que se vacíe el buffer habrá una pausa audible en la carga. Los cambios en el Z80 serían mínimos, sólo tendrías que añadir una NMI especial que cuando se dispara pone a 1 BOOTM y modificar RETN para que ponga BOOTM a 0. Y además estos pequeños cambios permitirían más cosas interesantes, por ejemplo.
-Cambiar el volumen, mostrando los valores por pantalla (aunque implicaría una pausa en el juego).
-Hacer cambios de configuración en caliente que no se guarden en la BIOS. Por ejemplo el tipo de joystick es muy común. Puede que no sepas qué controles tiene un juego, y el tener que reiniciar no es nada cómodo.
[Esta BRAM tiene que ser escribible, ya que se necesita una zona de memoria donde almacenar las partes de la pantalla que vamos a corromper para mostrar el OSD, puesto que al salir de la interrupción tendremos que restaurarla]

De todas formas hay determinados detalles que me he pasado por alto en cuanto a la implementación. Por ejemplo, a la hora de disparar la interrupción no es trivial saber cuándo se ha llenado el buffer. Supongamos que el buffer es de 16K. Cada instrucción PZX es variable, por lo que no podemos extraer nada del puntero de lectura del reproductor. Habría que poner un contador de instrucciones y que la parte software se encargara de inicializar y que el reproductor (llamo reproductor a lo que tienes implementado ahora que lee bloques PZX de RAM y lo transfiere al puerto EAR) decremente hasta llegar a 0. En ese momento lanza la interrupción especial. Este buffer sería un bloque de SRAM fijo que evidentemente no puede emplearse en otra cosa.

El software que atiende a esta interrupción se encargará de llenar el buffer de nuevo. Cuando se lee un archivo PZX sería más rápido, puesto que apenas tendría procesado (sólo habría que contar las instrucciones). Sin embargo en un TZX habría que traducir los bloques a PZX y esto sí que sería más lento. Los cortes los notarías cada 80 segundos si se emplea carga estándar (lo que tardan en cargarse 16K), cada 40s más o menos si es una carga turbo. Tampoco sería tan grave si cada 80 segundos se produce un corte de 1 segundo en la musiquilla de carga. Y si cargas un PZX el parón sería más corto aún.

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: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor mcleod_ideafix » 21 Jun 2015, 16:39

Vale. Ahora sí lo veo. Sí, lo que propones, aunque se carga un poco el rollo "carga turbo" al haber pausas, aunque sea mínimas, es factible. Lo que pasa es que necesitarás un montón de software. Si esto usa una memoria "shadow" que contiene el código que rellena el buffer, ese código tiene que tener una implementación al menos parcial de lo que es un sistema de ficheros FAT16/32, para poder leer los siguientes bloques de la tarjeta, y soporte para los comandos SPI de la propia tarjeta. En definitiva: que a lo que ocupa el reproductor de PZX, que sigue haciendo falta, le tienes que sumar las modificaciones que se le hagan al core T80 para soportar estas interrupciones "escondidas", la BRAM usada para el buffer, y todo el software que se necesita. No sé si compensa para evitar poner una memoria extra (que en mi caso es de 10ns, pero que podría ser de 100ns si no te importa que el retraso en el comienzo de algunos bloques sea un poco mayor)
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2013
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 8 veces

Re: ZX-UNO: reproductor de ficheros PZX dentro del propio cl

Mensajepor antoniovillena » 21 Jun 2015, 17:19

Exacto. Había dado erroneamente como posible implentar el buffer en SRAM en un bloque que no se utilice para otra cosa. Pero acabo de darme cuenta que aunque se pueda llenar si problemas, la parte reproductora de la FPGA tendrá problemas al vaciarla, ya que entra en colisión con el Z80 y la memoria de video.

Es cierto que es mucho trabajo, pero no habría que hacerlo ahora y a cambio sería una solución más viable para el público en general. Lo que sí puedes hacer es tener preparada la parte hardware necesaria para implementar la "difícil" (la software) cuando llegue el momento. Lo digo porque de esta forma no habría que buscar qué sacrificar de la FPGA más adelante. Los cambios serían:
  • Saber cuántos bloques BRAM de 16K quedan libres (porque algunos se emplearán para otras cosas como la paleta de ULAplus).
  • Supongamos que son 3 los bloques BRAM libres. Habría que mapearlos de alguna forma. El primer bloque (bootloader/software PZX) ya estaría mapeado en la parte baja de BOOTM=1. Los otros 2 se podrían extender con un sexto bit en MASTERMAPPER, o cualquier otra forma que requiera pocos recursos para implementarse. En este caso tendríamos 32K de buffer, lo que supone cortes cada 3 minutos más o menos.
  • El cambio en el core T80 que comenté antes, que sería mínimo.
  • Añadir las fuentes disparadoras de esta interrupción especial. Una de ellas sería el reproductor PZX cuando vacíe el buffer. Otra podrían ser todas las teclas de función que tenemos libres. Al comienzo de la rutina de interrupción podremos saber qué fuente ha provocado la interrupción (y qué tecla de función si ha sido por teclado).
  • Reducir la máquina de estados para que en lugar de un 15%, el reproductor PZX tenga una ocupación en FPGA sensiblemente inferior.


Volver a “Sinclair/Spectrum”

¿Quién está conectado?

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