snap2transfer, pasando de sna a tap con estilo

Aquí solo proyectos que incluyan el código fuente

Moderador: Fundadores

Reglas del Foro
Si no se incluyen los fuentes, se debe usar el foro de proyectos de software generales
Avatar de Usuario
flopping
Fundador
Fundador
Mensajes: 9971
Registrado: 29 Mar 2013, 15:26
Ubicación: Valencia
Been thanked: 122 times
Contactar:

Re: sna2transtape, pasando de sna a tap con estilo

Mensaje por flopping »

Zup, una cosa, ¿por que hacer un fichero tap con rayas?, ¿no se podria generar el tap sin rayas y con la pantalla limpia?, vamos, lo digo por que no le veo el sentido a tener un juego con rayas en la pantalla, vale que por nostalgia y demas, pero ¿no quedaria mejor sin esas rayas?, ya que como todos sabemos hay juegos que no refrescan la pantalla y es un fastidio tener el juego con las rayas permanentemente, recuerdo que en la epoca en la que salio el transtape, nunca me gusto ese interface, por que manchaba bastante mas la pantalla que otros interfaces.

Bueno, en resumen, ¿te has planteado crear una version de sna to tap "limpio"?, salu2.
No me hago responsable de mis post pues estan escritos bajo la influencia del alcohol y drogas psicotropicas, por la esquizofrenia paranoide.
(C) 1982-2024, 42 años de ZX Spectrum.
http://www.va-de-retro.com/ un foro "diferente".

Mi juego, que puedes descargar desde aqui
Avatar de Usuario
Zup !Sinclair 1
Aspirante a demonio
Aspirante a demonio
Mensajes: 241
Registrado: 27 Ene 2019, 17:41
Ubicación: Navarra
Been thanked: 14 times

Re: sna2transtape, pasando de sna a tap con estilo

Mensaje por Zup »

¿Pero es eso posible?

Estamos hablando de convertir un snapshot. En el caso de convertir un juego en tap, al final de la carga los registros no son críticos (el juego los suele inicializar), suele haber unos cuantos huecos en la RAM para colocar rutinas y, en casi todos los casos, se borran partes de la pantalla inmediatamente. Así que se puede elegir entre colocar nuestro cargador en alguno de estos huecos o en la pantalla, ya que se va a ver durante muy poco tiempo. El tema es que este es un método artesanal, no para herramientas automatizadas.

En el caso de un snapshot, hay que restaurar los 48k de memoria y todos los registros (si contamos la rutina para restaurarlos, eso son como 50 bytes). En un Spectrum "pelado" (sin ningún interface), hay que tirar de memoria de pantalla sí o sí. En el caso de un 128k, hay que añadir a esto el modo de paginación y todos los registros del AY (en mi programa no se contemplan porque los ficheros .sna no los almacenan). Aparte del valor nostálgico, las rayas del transtape me evitan tener que programar yo mismo la rutina que restaure los registros. Cuando adapte ese programa para que emule el Phoenix, las rayas serán más discretas.

¿Lo mejor que se puede hacer? Se me ocurren cuatro cosas, pero todas tienen desventajas.

Idea 1: Cargar el SCREEN$ original
En general, puede hacerse algo parecido a lo que hace el Specmate cuando carga dos pantallas: nada más comenzar la carga, se carga el SCREEN$ original del juego; el último bloque que se carga es el SCREEN$ del snapshot. Esto no ayuda con la corrupción, pero da un mejor aspecto a la copia.

Idea 2: un bloque de corrupción
Esto no tiene limitaciones, salvo que nos cargaremos unos cuantos caracteres enteros. En el interface Phoenix, se usan dos líneas contiguas de la pantalla. Simplemente empieza a ejecutar la rutina en la línea 1 y después salta al comienzo de la línea 2.
El método propuesto sería utilizar un bloque de 10 o 12 caracteres (líneas contiguas hacia abajo). Es muy poco eficiente porque se nos van a ir 6 bytes solo en cambiar el stack y saltar de línea a línea. Aún así, si se elige bien la ubicación de estos caracteres (p.ej.: línea 8, caracter 16, tenemos casi la total certeza de que esta parte de la pantalla no estará ocupada por elementos fijos (y que el programa la actualizará en algún momento). Incluso se podría poner un switch que cambiara entre dos ubicaciones alternativas en caso de que un programa tenga la mala leche de tener cosas ahí.
(Para que no quede tan feo, también se pueden cambiar los atributos para que quede un bloque negro en vez de un bloque de corrupción).

Idea 3: solo 8 bytes de corrupción
Las limitaciones son que esto se podría hacer solo para snapshots de 48k que se carguen en máquinas de 128k. Además, necesitaremos coger prestados 2 bytes más a la pila del programa. El proceso en sí sería parecido al que sigue cuando se usa el switch -b en sna2transtape:
- Cargamos parte de la memoria en la memoria alta del 128k (la RAM 3 es la más obvia), el resto se carga normalmente.
- Metemos la RAM 3 y restauramos lo que hemos guardado ahí.
- Sin salir de la RAM 3, empezamos a restaurar registros como locos (excepto bc, a y el estado de interrupciones).
- Copiamos una minirutina al centro de la pantalla (p. ej: línea 100 centrada, de nuevo la ubicación de la corrupción es la clave). La rutina consistiría en un ld bc,xxxx, ld a,xx, di o ei y un ret (¿son 8 o 9 bytes?).
- Cambiamos el SP al que debe tener el programa y metemos en la pila la dirección de esa minirutina.
- Lo último que ejecutamos desde la RAM 3 es un ld bc,32765; ld a,16 (o 48, según quieras bloquear o no la paginación); jp 7805.
- De ahí ya se ejecuta nuestra minirutina y cedemos el control al juego.
Una variante de esto sería que nuestra rutina fuera algo así como (dir);(bc);(af);pop bc; pop af; ld sp,xxxx; ei|di; ret (13 bytes) y usamos la pantalla con un ministack (6 bytes) temporal para no gastar el del programa.

Idea 4: Sin ninguna raya
De nuevo esto solo es para snapshots de 48k, pero subimos los requerimientos a un +2A o +3. Además, el programa no podrá usar el puerto de paginación y nos vamos a cargar los timings del juego.
En este caso, habría que usar el modo all-ram de los +2A/+3, en alguno de los modos que usan la RAM 5 como segunda página (p.ej: 4,5,6,7). Básicamente, cargamos la RAM del juego en las páginas 5, 6 y 7. Luego, copiamos la ROM del Spectrum en la página 4.
Al final de la original del Spectrum hay un "hueco" (que no está presente en la del +2A o +3). En teoría, podríamos colocar ahí la rutina que restaure los registros por lo que no habría ni un solo byte colgando en la pantalla. En la práctica, habrá un montón de juegos que fallarán (vectores de interrupción, una ROM no exactamente igual) y la contención de memoria no es la misma que en un 48k normalito.

Son varias ideas para un programa que no alterara los marcadores... pero entonces dejaría de ser sna2transtape.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Avatar de Usuario
Zup !Sinclair 1
Aspirante a demonio
Aspirante a demonio
Mensajes: 241
Registrado: 27 Ene 2019, 17:41
Ubicación: Navarra
Been thanked: 14 times

Re: sna2transtape, pasando de sna a tap con estilo

Mensaje por Zup »

He ido actualizando tan rápido que ni he puesto los mensajes... ahora el programa va por la versión 1.20.

Las dos grandes novedades son:
- Ya convierte ficheros de 128k.
- En los ficheros de 128k, se detecta el primer y último byte usado de cada página para reducir el tamaño de los tap (y tiempo de carga). Se ha añadido el switch -t para desactivar este comportamiento (y crear copias que cargan explícitamente toda la memoria).

Este "recorte" ha traído a la luz un pequeño detalle de los Spectrum 128k... no inicializan toda la RAM a 0. O más bien la inicializan, pero luego la usan. En toda la gama de 128k siempre se usa de la página 7, por lo que el snapshot siempre tiene bytes usados en la RAM 7. En el caso de los +2A y +3 el uso de la RAM 7 se amplía y además se usan las RAM 1, 3, 4 y 6 para el RAMDisk.

¿Resultado? Un Snapshot de Fairlight sacado en un +2 tarda en cargar 8m 06s, mientras que el mismo snapshot sacado en un +3 se va a los 12m 19s (más o menos lo que tardaría en cargar una copia completa de la RAM). Por contra, un snapshot sacado de una máquina en la que previamente se ha puesto a cero (casi) toda la RAM tarda 7m 45s.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Avatar de Usuario
Zup !Sinclair 1
Aspirante a demonio
Aspirante a demonio
Mensajes: 241
Registrado: 27 Ene 2019, 17:41
Ubicación: Navarra
Been thanked: 14 times

Re: sna2transtape, pasando de sna a tap con estilo

Mensaje por Zup »

Vale, creo que esta va a ser una de las últimas actualizaciones al programa. Las novedades son:
- Bugfix para las versiones 1.02 y 1.20... no las había testeado lo suficiente. Se habían escapado un bug que causaba que los ficheros de 128k solo se convirtieran al utilizar -v, y otro que hacía que las cargas tuvieran una alta probabilidad de fallar en +2A/+3.
- Nueva versión 1.24. En esta versión se ha añadido un algoritmo de compresión RLE, lo que acorta tiempos de carga (no es demasiado espectacular, pero resuelve los tiempos de carga con snapshots de +3). Esto está controlado con el switch -t. Si lo ponemos, se hace un fichero .tap XXL con toda la memoria; si no lo ponemos el programa aplicará los algoritmos de recorte y compresión.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Avatar de Usuario
Zup !Sinclair 1
Aspirante a demonio
Aspirante a demonio
Mensajes: 241
Registrado: 27 Ene 2019, 17:41
Ubicación: Navarra
Been thanked: 14 times

Re: sna2transfer, pasando de sna a tap con estilo

Mensaje por Zup »

Creo que ya este programa ya está terminado (salvo informes de bugs), así que he subido la versión 1.28. Las novedades son:
- Se sustituye la compresión RLE de 16 bits por RLE de 8 bits. Los ficheros se comprimen algo menos, pero la rutina es mucho más clara.
- Se añade sna2phoenix, el equivalente usando el formato del Phoenix (corrupción de pantalla más discreta).
- Se añade sp2transtape, homenaje al emulador de Pedro Gimeno.
- Se añade sna2zx7, que utiliza la rutina de arranque de Phoenix (misma corrupción) pero comprime casi toda la RAM usando el algoritmo zx7.
- Se han vuelto a "barajar" las funciones y repartirlas de una manera más racional (¿seguro?) en los ficheros .h para evitar duplicidades de código.

Dos cosas a destacar:
- El cargador original del Phoenix no creo que sea 100% compatible con todos los dispositivos (especialmente con el DivIDE), así que se usa un cargador alternativo y compatible. Si se usa sna2phoenix con el switch -s, se generará un .tap idéntico al de Phoenix... incluyendo el problemático cargador original.
- Mientras programaba sna2zx7 tuve que consultar con su autor acerca de un comportamiento no esperado. Si comprime datos "revueltos", la compresión es muy rápida; si comprime datos con muchas repeticiones (por ejemplo, esas páginas llenas de 0xE5 del +3), la compresión es asquerosamente lenta. Al parecer, es un comportamiento normal... menos mal que los tap se generan solo una vez.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Avatar de Usuario
dandare
Hermano de Lucifer
Hermano de Lucifer
Mensajes: 3718
Registrado: 09 Feb 2016, 15:09
Ubicación: I Register
Been thanked: 6 times

Re: snap2transfer, pasando de sna a tap con estilo

Mensaje por dandare »

En relación a las manchas de pantalla en carga de SNAs, una vía que hemos investigado hace tiempo es que hay un número considerable de snapshots que tienen zonas consecutivas de memoria con datos repetidos (20, 30 ... 100 bytes iguales). Aprovechando esta situación, se puede meter todo el grueso del cargador ahí y luego sacrificar unos pocos bytes de pantalla, o de pila, para restaurar ese trozo a su valor original.
Tenemos varios procedimientos automáticos que utilizan cosas similares en los dandanators.
Otra opción, más compleja pero potente, es utilizar un sistema que encuentre "gadgets" adecuados, al estilo ROP (Return-oriented programming), y sacrificar unos pocos bytes de la pila. Esto, en combinación con los huecos que comentaba antes, ofrece oportunidades interesantes.
Imagen
Imagen
Avatar de Usuario
Zup !Sinclair 1
Aspirante a demonio
Aspirante a demonio
Mensajes: 241
Registrado: 27 Ene 2019, 17:41
Ubicación: Navarra
Been thanked: 14 times

Re: snap2transfer, pasando de sna a tap con estilo

Mensaje por Zup »

dandare escribió:En relación a las manchas de pantalla en carga de SNAs, una vía que hemos investigado hace tiempo es que hay un número considerable de snapshots que tienen zonas consecutivas de memoria con datos repetidos (20, 30 ... 100 bytes iguales).
Es una solución interesante, pero difícil de automatizar. Ya de primeras habría que comprobar si I está apuntando a esa zona (esté o no esté IM2 activado), y aún así no tienes pistas de si vas a sobreescribir algo importante (y lo que jode más, puede que sobreescribas algo de lo que no te enteres hasta que hayas avanzado bastante en el juego).
dandare escribió:Aprovechando esta situación, se puede meter todo el grueso del cargador ahí y luego sacrificar unos pocos bytes de pantalla, o de pila, para restaurar ese trozo a su valor original.
Realmente solo se necesitan unos 60 bytes para restaurar los registros de la CPU (entre rutina y stack). Por otra parte, no me gusta nada lo de la pila... no sabes cuánto espacio dedicaron originalmente los programadores a la pila ni cuánto está utilizado, así que no sabes si todos tus bytes van a poder caber ahí dentro (p.ej.: un juego dedica 64 bytes, pero en el momento del snapshot había metido cosas por valor de 50... no es crítico pero tampoco una situación cómoda).
dandare escribió:Tenemos varios procedimientos automáticos que utilizan cosas similares en los dandanators.
Otra opción, más compleja pero potente, es utilizar un sistema que encuentre "gadgets" adecuados, al estilo ROP (Return-oriented programming), y sacrificar unos pocos bytes de la pila. Esto, en combinación con los huecos que comentaba antes, ofrece oportunidades interesantes.
Realmente la opción más razonable (de cara a eliminar la corrupción en pantalla) sería disponer de RAM extra. Arriba ya había comentado cómo hacerlo en un 128k a costa de sacrificar únicamente 9 bytes de la pantalla, pero en el caso de disponer RAM paginada sobre ROM (p.ej.: el pokeador automático o un DivIDE) podría meter la rutina de arranque y el stack en esa zona y arrancar el juego sin tocar para nada ni pantalla ni stack (salvo los 2 bytes obligatorios).

En cualquier caso, esto era una prueba de concepto y un homenaje a los juegos pirateados con transfer... aunque claramente se me ha ido de las manos. En el fondo creo que tanto sna2transtape como sna2phoenix solo deberían imitar los transfers correspondientes (dejando los snapshots de 128k a sna2zx7, y eliminando las opciones -v, -f, -b y -t). Quizás incluiría en la colección un sna2ramjet para tener un transfer de 128k, y un sna2tapbas modificado (carga todo desde BASIC, y solo corrompe solo esos 9 bytes que hablaba antes). Pero ahora mismo (salvo que alguien chille algo acerca de un bug) creo que voy a dejar reposar este tema una temporada.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Responder

Volver a “Proyectos de software abiertos”